由于之前没写过网络流方面的题目,所以第一次写的时候居然想到用动态规划去做(在没有环的情况下貌似可以,有环会RE)。现在看来,这题是个求最小割的题,因为最大流量最小割相等,所以也就是求最大流量。容量网络也很明显。我用的是标号法(Edmonds-Karp算法)。
#include <stdio.h> #include <string.h> #define N 152 #define INF 0x7fffffff #define MIN(a,b) ((a)<(b)?(a):(b)) int c[N][N],flow[N][N],a[N],p[N],f,n,m; int queue[N],front,rear; void EK(int s,int t) { int u,v; f=0; memset(flow,0,sizeof(flow)); while(1) { memset(a,0,sizeof(a)); front=rear=0; queue[rear]=s,rear=(rear+1)%N; a[s]=INF,p[s]=0; while(rear!=front) { u=queue[front],front=(front+1)%N; for(v=1;v<=n;v++) { if(!a[v]&&c[u][v]>flow[u][v]) { a[v]=MIN(a[u],c[u][v]-flow[u][v]); p[v]=u; queue[rear]=v,rear=(rear+1)%N; } } } if(!a[t]) break; for(u=t;u!=s;u=p[u]) { flow[p[u]][u]+=a[t]; flow[u][p[u]]-=a[t]; } f+=a[t]; } } int main() { int i,x,y,z,s,t; while(~scanf("%d%d",&n,&m)) { memset(c,0,sizeof(c)); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); c[x][y]+=z; } scanf("%d%d",&s,&t); EK(s,t); printf("%d\n",f); } return 0; }