怒搞一下午网络流,又去我一块心病。
从2F到SAP再到Dinic终于过掉了。可是书上说Dinic的时间复杂度为v*v*e。感觉也应该超时的啊,可是过掉了,好诡异。
后两种算法都是在第一种的基础上进行优化。第一种方法就是不停的寻找增广路,后两种引进了层次网络的概念,第三种又改善了寻找增广路的方法。
现在只能理解到这里了。。。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 6000007 using namespace std; struct E { int u,v,Max,now,next; }edge[30000]; int Top; int head[300]; void Link(int u,int v,int w) { edge[Top].u = u; edge[Top].v = v; edge[Top].Max = w; edge[Top].now = 0; edge[Top].next = head[u]; head[u] = Top++; } struct P { int pre,now,floor; bool mark; }sta[300]; void Modify(int a,int t) { while(t != 1) { edge[sta[t].pre].now += a; t = edge[sta[t].pre].u; } } int SAP(int s,int t,int n) { for(int i = 1;i <= n; ++i) sta[i].mark = false; queue<int> q; q.push(s); sta[s].mark = true; sta[s].now = 2000000000; sta[s].pre = -1; while(q.empty() == false) { if(sta[t].mark && sta[t].now) { Modify(sta[t].now,t); return sta[t].now; } int f = q.front(); q.pop(); for(int p = head[f];p != -1; p = edge[p].next) { if(sta[edge[p].v].mark == false && sta[edge[p].u].floor == sta[edge[p].v].floor-1 && sta[edge[p].u].floor < sta[t].floor) { sta[edge[p].v].now = min(sta[f].now,edge[p].Max - edge[p].now); if(sta[edge[p].v].now == 0) continue; sta[edge[p].v].pre = p;//记录边的存储位置 sta[edge[p].v].mark = true; q.push(edge[p].v); } } } return 0; } void Updata_Floor(int s,int t,int n) { queue<int> q; for(int i = 0;i <= n; ++i) sta[i].mark = false,sta[i].floor = n; q.push(s); sta[s].mark = true; sta[s].floor = 1; while(q.empty() == false) { int f = q.front(); q.pop(); if(sta[t].mark && sta[t].floor <= sta[f].floor) return ; for(int p = head[f];p != -1; p = edge[p].next) { if(sta[edge[p].v].mark == false && edge[p].now < edge[p].Max) { sta[edge[p].v].mark = true; sta[edge[p].v].floor = sta[f].floor + 1; q.push(edge[p].v); } } } } int dfs(int s,int t,int a) { if(s == t) return a; int f = 0; for(int p = head[s],temp = 0;p != -1; p = edge[p].next) { if((sta[edge[p].v].floor < sta[t].floor || edge[p].v == t) && sta[edge[p].v].floor == sta[s].floor+1 && edge[p].now < edge[p].Max) { temp = dfs(edge[p].v,t,min(a-f,edge[p].Max-edge[p].now)); edge[p].now += temp; f += temp; } } return f; } int Dinic(int s,int t,int n) { return dfs(s,t,200000000); } int Cal_Max_Flow(int s,int t,int n) { int temp,f = 0; do { Updata_Floor(s,t,n); //temp = SAP(s,t,n); temp = Dinic(s,t,n); f += temp; }while(temp); return f; } int main() { char s[50]; int i,n,np,nc,m,u,v,w; while(scanf("%d %d %d %d",&n,&np,&nc,&m) != EOF) { memset(head,-1,sizeof(head)); Top = 0; for(i = 0;i < m; ++i) { scanf("%s",s); sscanf(s,"(%d,%d)%d",&u,&v,&w); Link(u+2,v+2,w); } for(i = 0;i < np; ++i) { scanf("%s",s); sscanf(s,"(%d)%d",&u,&w); Link(1,u+2,w); } for(i = 0;i < nc; ++i) { scanf("%s",s); sscanf(s,"(%d)%d",&u,&w); Link(u+2,n+2,w); } printf("%d\n",Cal_Max_Flow(1,n+2,n+2)); } return 0; }