poj 3228(二分+最大流)
题目链接:http://poj.org/problem?id=3228
思路:增设一个超级源点和一个超级汇点,源点与每一个gold相连,容量为gold数量,汇点与仓库相连,容量为仓库的容量,然后就是二分最小的最大相邻距离,跑最大流验证即可。最大流用的是别人的Dinic模版。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 222 8 #define inf 1<<30 9 10 int vs,vt; 11 int dep[MAXN]; 12 int map[MAXN][MAXN]; 13 14 int gold[MAXN],store[MAXN]; 15 int dist[MAXN][MAXN]; 16 void Build_Map(int limit,int n) 17 { 18 memset(map,0,sizeof(map)); 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 if(dist[i][j]<=limit)map[i][j]=inf; 22 for(int i=1;i<=n;i++){ 23 map[vs][i]=gold[i]; 24 map[i][vt]=store[i]; 25 } 26 } 27 28 int BFS(){ 29 queue<int> q; 30 while(!q.empty()) 31 q.pop(); 32 memset(dep,-1,sizeof(dep)); 33 dep[vs]=0; 34 q.push(vs); 35 while(!q.empty()){ 36 int u=q.front(); 37 q.pop(); 38 for(int v=vs;v<=vt;v++) 39 if(map[u][v]>0 && dep[v]==-1){ 40 dep[v]=dep[u]+1; 41 q.push(v); 42 } 43 } 44 return dep[vt]!=-1; 45 } 46 47 int DFS(int u,int minx){ 48 if(u==vt) 49 return minx; 50 int tmp; 51 for(int v=vs;v<=vt;v++) 52 if(map[u][v]>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(minx,map[u][v])))){ 53 map[u][v]-=tmp; 54 map[v][u]+=tmp; 55 return tmp; 56 } 57 dep[u]=-1; 58 return 0; 59 } 60 61 int Dinic(){ 62 int ans=0,tmp; 63 while(BFS()){ 64 while(1){ 65 tmp=DFS(vs,inf); 66 if(tmp==0) 67 break; 68 ans+=tmp; 69 } 70 } 71 return ans; 72 } 73 74 int main() 75 { 76 int total,n,m,a,b,c; 77 while(~scanf("%d",&n)){ 78 if(n==0)break; 79 total=0,vs=0,vt=n+1; 80 for(int i=1;i<=n;i++) 81 for(int j=1;j<=n;j++) 82 dist[i][j]=inf; 83 for(int i=1;i<=n;i++){ 84 scanf("%d",&gold[i]); 85 total+=gold[i]; 86 } 87 for(int i=1;i<=n;i++)scanf("%d",&store[i]); 88 scanf("%d",&m); 89 while(m--){ 90 scanf("%d%d%d",&a,&b,&c); 91 dist[a][b]=dist[b][a]=c; 92 } 93 94 int low=0,high=100010,mid,ans=-1; 95 while(low<=high){ 96 mid=(low+high)>>1; 97 Build_Map(mid,n); 98 if(Dinic()==total){ 99 ans=mid; 100 high=mid-1; 101 }else 102 low=mid+1; 103 } 104 if(ans==-1){ 105 printf("No Solution\n"); 106 }else 107 printf("%d\n",ans); 108 } 109 return 0; 110 } 111 112 113