题意:
有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;
}