http://acm.fzu.edu.cn/problem.php?pid=1887
按照题目要求先求出每个联通分支,然后在每个联通分支里面按照单位花费,从小到大排序,贪心一下就行了。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
usingnamespacestd;
constintmaxn=105;
structnode
{
doublex;
doubley;
intvnum;
inttnum;
intpnum;
intcost;
}a[maxn];
intvis[maxn];
booloperator<(nodep,nodeq)
{
returnp.cost>q.cost;
}
priority_queue<node>pq;
vector<int>v[maxn];
intn=0,sum1=0,sum2=0;
doubler=0;
constdoubleeps=1e-8;
doubleDist(inti,intj)
{
returnsqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
voiddfs(intt)
{
vis[t]=1;
sum1+=a[t].pnum;
sum2+=a[t].vnum;
pq.push(a[t]);
for(inti=1;i<=n;i++)
{
if(vis[i]==1||Dist(t,i)>r+eps)
continue;
dfs(i);
}
}
intmain()
{
intt=1,T,maxp=0,minc=0;
scanf("%d",&T);
while(T--)
{
maxp=0;
minc=0;
scanf("%d%lf",&n,&r);
for(inti=1;i<=n;i++)
scanf("%lf%lf%d",&a[i].x,&a[i].y,&a[i].vnum);
for(inti=1;i<=n;i++)
scanf("%d%d",&a[i].tnum,&a[i].cost);
for(inti=1;i<=n;i++)
scanf("%d",&a[i].pnum);
memset(vis,0,sizeof(vis));
for(inti=1;i<=n;i++)
{
if(vis[i]==1)
continue;
while(pq.size()>0)
pq.pop();
sum1=0;
sum2=0;
dfs(i);
if(sum2>=sum1)
{
maxp+=sum1;
continue;
}
maxp+=sum2;
sum1-=sum2;
while(pq.size()>0&&sum1>0)
{
nodetmp=pq.top();
pq.pop();
if(sum1>=tmp.tnum)
{
sum1-=tmp.tnum;
maxp+=tmp.tnum;
minc+=tmp.cost*tmp.tnum;
}
else
{
maxp+=sum1;
minc+=tmp.cost*sum1;
sum1=0;
}
}
}
printf("Case%d:%d%d\n",t++,maxp,minc);
}
return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理