UVALive - 7018 Dragons

本文针对一项ACM竞赛中的特定算法问题进行了深入分析,提出了直接杀敌与消耗战两种策略,并通过具体实例代码展示了如何利用派兵数量和增长速度解决难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目网址点击打开链接

开始以为只需要选择最大Ni然后根据SI与Ni关系更新寻找到Ni比答案也小就好了,原来的思路写wa了,

唉,,,但是可以进一步写一下;

对于每个城市团,转移时间可以忽略不计,但是注意每一个团必须要派兵;

对于派兵杀龙发现,只要总兵数大于龙头增长数,一定可以杀死,只是时间问题;

所以,按增长排序大小以后,每个龙,可以派他原来的头数去直接杀死他,也可以只要比他增长头数大1来磨死它;

因此把每个团单数分开来看,如果当前派兵数+Si<+Ni,那么只需要在加SI去杀;否则,看当前兵数,是否可以磨死它

wa到不开心,一开始单独把两种分开写的,但是wa了,可能还会有,也许两种混合为最优的情况吧。

妈耶,,,

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include<algorithm>
#include<vector>
#include<set>

using namespace std;
const int maxn=300+5;
const int maxd=1000+5;
int N,M,K;
int inter[maxn][maxn];
int pro[maxn];
long long ans[maxn];
long long ans2[maxn];
struct node
{
    long long  c,s,n;
    node(){}
    node(long long cc,long long  ss,long long nn):c(cc),n(nn),s(ss){}
    bool operator<(const node&S)const
    {
        //if(n!=S.n)
           return n>S.n;
       // else
           // return r>S.r;
    }
};
node dra[maxd];
int vis[maxd];
int vis2[maxd];
void init(int n)
{
    for(int i=0;i<=n;i++)
        pro[i]=i;
}
int find(int x)
{
    if(x==pro[x])
        return x;
    return pro[x]=find(pro[x]);
}
void uion(int x,int y)
{
    int xx=find(x);
    int yy=find(y);
    if(xx==yy)
        return;
    else
        pro[xx]=yy;
}
int same(int x,int y)
{
    return find(x)==find(y);
}
int main()
{
    while(cin>>N>>M>>K&&N&&M&&K)
    {
        int a,b;
        //int ans=0;
        long long res=0;
        memset(vis,0,sizeof(vis));
        memset(ans,0,sizeof(ans));
        init(N);
        for(int i=0;i<M;i++)
        {
            cin>>a>>b;
            uion(a,b);
        }
        for(int i=0;i<K;i++)
        {
            cin>>dra[i].c>>dra[i].s>>dra[i].n;
        }
        sort(dra,dra+K);
        for(int i=0;i<K;i++)
        {
            int t=find(dra[i].c);
            if(ans[t]+dra[i].s<=dra[i].n+1)
               ans[t]+=dra[i].s;
            else
               ans[t]=max(ans[t],dra[i].n+1);
        }
        memset(vis,0,sizeof(vis));
        for(int i=0;i<K;i++)
        {
            int t=find(dra[i].c);
            if(vis[t])
                continue;
            else
            {
                res+=ans[t];
                vis[t]=1;

            }
        }
        cout<<res<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值