当前位置: 代码迷 >> 综合 >> poj 3228 Gold Transportation 并查集
  详细解决方案

poj 3228 Gold Transportation 并查集

热度:69   发布时间:2024-01-19 05:49:18.0

题意:

有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;	
}