1 //[转] : http://blog.csdn.net/moon_1st/article/details/5365886 2 //网络流中求最大流几乎最快的算法——最高标号预流推进算法(HLPP)
//不过这里不含GAP优化,GAP优化见本blog《浅谈网络流的基本算法[转]》 (注: 没有gap优化似乎HLPP很渣啊~ ) 3 //思路很直接,略 4 //代码很清晰, 注释略 5 6 7 #include <iostream> 8 #define Max 65535 9 using namespace std; 10 11 int s,t,n,np,nc,m,level; 12 int h[103],e[103],d[103],list[103][103],f[103][103],c[103][103]; 13 char str[50]; 14 bool visit[103]; 15 16 int min(int x,int y) 17 { 18 return x<y? x:y; 19 } 20 int max(int x,int y) 21 { 22 return x>y? x:y; 23 } 24 25 void bfs() 26 { 27 int head,tail,i,x; 28 memset(d,0,sizeof(d)); 29 memset(visit,false,sizeof(visit)); 30 memset(h,0,sizeof(h)); 31 d[0]=t; 32 head=tail=0; 33 visit[t]=true; 34 while(head<=tail) 35 { 36 x=d[head++]; 37 for(i=0;i<n;i++) 38 if(!visit[i]&&c[i][x]>0) 39 { 40 d[++tail]=i; 41 visit[i]=true; 42 h[i]=h[x]+1; 43 } 44 } 45 h[s]=n-1; 46 } 47 48 void init() 49 { 50 int i,x,y,z; 51 memset(f,0,sizeof(f)); 52 memset(c,0,sizeof(c)); 53 memset(e,0,sizeof(e)); 54 s=n; 55 t=n+1; 56 n+=2; 57 for(i=1;i<=m;i++) 58 { 59 scanf("%s",&str); 60 sscanf(str,"(%d,%d)%d",&x,&y,&z); 61 c[x][y]=z; 62 } 63 for(i=1;i<=np;i++) 64 { 65 scanf("%s",&str); 66 sscanf(str,"(%d)%d",&x,&z); 67 c[s][x]=z; 68 } 69 for(i=1;i<=nc;i++) 70 { 71 scanf("%s",&str); 72 sscanf(str,"(%d)%d",&x,&z); 73 c[x][t]=z; 74 } 75 76 bfs(); 77 78 memset(list,0,sizeof(list)); 79 for(i=0;i<n;i++) 80 if(c[s][i]>0) 81 { 82 e[s]-=c[s][i]; 83 e[i]+=c[s][i]; 84 f[s][i]+=c[s][i]; 85 f[i][s]=-f[s][i]; 86 } 87 88 for(i=0;i<n-2;i++) 89 if(e[i]>0) 90 { 91 list[h[i]][0]++; 92 x=list[h[i]][0]; 93 list[h[i]][x]=i; 94 } 95 } 96 97 98 void push(int u,int v) 99 { 100 int tem,x; 101 tem=min(e[u],c[u][v]-f[u][v]); 102 if(e[v]==0&&v!=s&&v!=t) 103 { 104 list[h[v]][0]++; 105 x=list[h[v]][0]; 106 list[h[v]][x]=v; 107 if(h[v]>level) 108 level=h[v]; 109 } 110 e[u]-=tem; 111 e[v]+=tem; 112 f[u][v]+=tem; 113 f[v][u]=-f[u][v]; 114 } 115 116 117 void relabel(int v) 118 { 119 int i,mh=Max; 120 for(i=0;i<n;i++) 121 if(i!=v&&h[i]>=h[v]&&c[v][i]-f[v][i]>0) 122 mh=min(mh,h[i]); 123 h[v]=mh+1; 124 level=h[v]; 125 list[level][0]++; 126 list[level][1]=v; 127 } 128 129 void push_relabel() 130 { 131 int i,v,tem,flag; 132 level=0; 133 for(i=0;i<n-2;i++) 134 if(e[i]>0) 135 level=max(level,h[i]); 136 137 while(level) 138 { 139 tem=list[level][0]; 140 v=list[level][tem]; 141 list[level][0]--; 142 while(level>0&&list[level][0]==0) 143 level--; 144 flag=false; 145 for(i=0;i<n;i++) 146 { 147 if(e[v]==0) break; 148 if(h[i]+1==h[v]&&c[v][i]-f[v][i]>0) 149 { 150 push(v,i); 151 flag=true; 152 } 153 } 154 if(!flag || e[v]>0) 155 relabel(v); 156 } 157 } 158 159 160 161 int main() 162 { 163 while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) 164 { 165 init(); 166 push_relabel(); 167 cout<<e[t]<<endl; 168 } 169 return 0; 170 }