Http://acm.fzu.edu.cn/problem.php? PID = 1, 1887
Find each Unicom branch according to the requirement of the subject, and then sort it by unit cost in each Unicom branch from small to large. just greedy.
#include <iostream>#include <cstdio>#include <string.h>#include <cmath>#include <algorithm>#include <vector>#include <queue>using namespace std;const int maxn = 105;struct node{double x;double y;int vnum;int tnum;int pnum;int cost;}a[maxn];int vis[maxn];bool operator < (node p,node q){return p.cost>q.cost;}priority_queue<node>pq;vector<int>v[maxn];int n=0,sum1=0,sum2=0;double r=0;const double eps = 1e-8;double Dist(int i,int j){return sqrt( (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));}void dfs(int t){vis[t]=1;sum1+=a[t].pnum;sum2+=a[t].vnum;pq.push(a[t]);for(int i=1;i<=n;i++){ if(vis[i]==1 || Dist(t,i)>r+eps) continue; dfs(i);}}int main(){ int t=1,T,maxp=0,minc=0;scanf("%d",&T);while(T--){maxp=0;minc=0;scanf("%d %lf",&n,&r);for(int i=1;i<=n;i++)scanf("%lf %lf %d",&a[i].x,&a[i].y,&a[i].vnum);for(int i=1;i<=n;i++) scanf("%d %d",&a[i].tnum,&a[i].cost);for(int i=1;i<=n;i++)scanf("%d",&a[i].pnum); memset(vis,0,sizeof(vis)); for(int i=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){node tmp = 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);}return 0;}