将每个城市拆成两个点,他们之间的流量就是这个城市的值,不同城市之间的流量是无穷,这样走一遍最大流就可以了。
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <string> #include <queue> #include <math.h> using namespace std; const int maxn=100005; const int INF=999999999; struct Edge { int from,to,cap,next; }; int n,m,k,s,t; int d[maxn]; int head[maxn]; struct Edge edge[maxn*4]; void AddEdge(int u,int v,int w) { edge[k].from=u; edge[k].to=v; edge[k].cap=w; edge[k].next=head[u]; head[u]=k++; edge[k].from=v; edge[k].to=u; edge[k].cap=0; edge[k].next=head[v]; head[v]=k++; } int BFS() { memset(d,-1,sizeof(d)); queue<int> q; q.push(s); d[s]=0; while(!q.empty()) { int x=q.front(); q.pop(); for(int i=head[x];i!=-1;i=edge[i].next) { int u=edge[i].to; if(edge[i].cap>0 && d[u]==-1) { d[u]=d[x]+1; q.push(u); } } } return d[t]; } int DFS(int x,int num) { if(x==t || num==0) return num; int flow=0,f; for(int i=head[x];i!=-1;i=edge[i].next) { int u=edge[i].to; if(d[u]==d[x]+1 && edge[i].cap) { f=min(edge[i].cap,num); f=DFS(u,f); edge[i].cap-=f; edge[i^1].cap+=f; flow+=f; num-=f; if(num==0) break; } } return flow; } int dinic() { int ans=0; while(BFS()!=-1) { ans+=DFS(s,INF); } return ans; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); scanf("%d%d",&s,&t); k=0; for(int i=1;i<=n;i++) { int p; scanf("%d",&p); AddEdge(i,i+n,p); //拆点 } for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); AddEdge(u+n,v,INF); //不同城市之间流量无穷大 AddEdge(v+n,u,INF); } t=t+n; int ans=dinic(); printf("%d\n",ans); } return 0; }
原文:http://blog.csdn.net/mfmy_szw/article/details/19208269