题意:
有n和城市和m条路,每个城市都有产生金量和收集金量,现在要把所有黄金收集,求经过的最短边是多少。
分析:
二分+最大流或用并查集合并等价类。
//poj 3228 //sep9 #include <iostream> #include <algorithm> using namespace std; const int maxN=256; const int maxM=10024; int p[maxN],sum[maxN]; struct Edge { int u,v,w; }e[maxM]; int cmp(Edge a,Edge b) { return a.w<b.w; } int find(int u) { if(p[u]==u) return u; int x=find(p[u]); sum[x]+=sum[u]; sum[u]=0; return p[u]=x;; } int main() { int n,m,x; while(scanf("%d",&n)==1&&n){ for(int i=1;i<=n;++i){ sum[i]=0; p[i]=i; } for(int i=1;i<=n;++i){ scanf("%d",&x); sum[i]-=x; } for(int i=1;i<=n;++i){ scanf("%d",&x); sum[i]+=x; } scanf("%d",&m); for(int i=0;i<m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); sort(e,e+m,cmp); int ok=0,ans=-1; for(int i=0;i<m;++i){ int u=e[i].u; int v=e[i].v; int pu=find(u); int pv=find(v); if(pu!=pv){ p[pu]=pv; sum[pv]+=sum[pu]; sum[pu]=0; } int ok=1; for(int j=1;j<=n;++j) if(p[j]==j&&sum[j]<0){ ok=0; break; } if(ok==1){ ans=i; break; } } if(ans==-1) puts("No Solution"); else printf("%d\n",e[ans].w); } return 0; }
时间: 2024-10-26 03:03:42