题目网址点击打开链接
开始以为只需要选择最大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;
}