差不多三天的时间过去了,学了一个网络流最大流。。
现在来总结一下。。。
先说一下之前那个ek的算法,说实话,这个算法本质上很好去理解,就是利用一个广搜不断的搜出所谓的增广路径。
View Code
1 #include<iostream> 2 #include<string.h> 3 #include<queue> 4 #define N 110 5 using namespace std; 6 int map[N][N]; 7 int n,np,nc,m,s,e,w; 8 int link[N],num[N],answer; 9 char temp[20]; 10 int bfs() 11 { 12 queue<int> q; 13 num[n]=0x7fffffff; 14 q.push(n); 15 for(int i=0;i<=n+1;i++)link[i]=-1; 16 while(!q.empty()) 17 { 18 int cur=q.front(); 19 q.pop(); 20 if(cur==n+1) 21 { 22 answer+=num[n+1]; 23 int from,now=n+1; 24 while(now!=n) 25 { 26 from=link[now]; 27 map[from][now]-=num[n+1]; 28 map[now][from]+=num[n+1]; 29 now=from; 30 } 31 while(!q.empty())q.pop(); 32 num[n]=0x7fffffff; 33 for(int i=0;i<=n+1;i++)link[i]=-1; 34 q.push(n); 35 continue; 36 } 37 for(int i=0;i<=n+1;i++) 38 { 39 if(map[cur][i]&&link[i]==-1) 40 { 41 link[i]=cur; 42 num[i]=num[cur]<map[cur][i]?num[cur]:map[cur][i]; 43 q.push(i); 44 } 45 } 46 } 47 return answer; 48 } 49 int main() 50 { 51 while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) 52 { 53 for(int i=0;i<=n+1;i++) 54 { 55 for(int j=0;j<=n+1;j++) 56 { 57 map[i][j]=0; 58 } 59 } 60 while(m--) 61 { 62 getchar(); 63 scanf("%s",temp); 64 int i=1,len=strlen(temp); 65 s=e=w=0; 66 while(temp[i]!=','){s=s*10+temp[i]-'0';i++;} 67 i++; 68 while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;} 69 i++; 70 while(i<len){w=w*10+temp[i]-'0';i++;} 71 map[s][e]+=w; 72 } 73 while(np--) 74 { 75 scanf("%s",temp); 76 int i=1,len=strlen(temp); 77 s=w=0; 78 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;} 79 i++; 80 while(i<len){w=w*10+temp[i]-'0';i++;} 81 map[n][s]+=w; 82 } 83 while(nc--) 84 { 85 scanf("%s",temp); 86 int i=1,len=strlen(temp); 87 s=w=0; 88 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;} 89 i++; 90 while(i<len){w=w*10+temp[i]-'0';i++;} 91 map[s][n+1]+=w; 92 } 93 answer=0; 94 printf("%d\n",bfs()); 95 } 96 return 0; 97 }
虽然这个算法比较好理解,但是在时间上面确实是十分的底下的。。
所以开始了sap的学习,现在设置一个距离标号为dis[i],表示i节点和终点的距离。首先先全部初始化为0,然后若现在有一条路径k->t->终点,则表示dis[k]=dis[t]+1;ok了,说了这个,说实话应该会看的比较懂的。。
不过下面有两种样式的代码,一个是递归的,比较好理解,而非递归的就是在模拟递归一样,不要被代码长度吓到,不过说实话,我那个时候还是被吓到了的…
View Code
1 #include<iostream> 2 #define min(a,b) a<b?a:b 3 #define Inf 0x7fffffff 4 #define N 110 5 using namespace std; 6 int n,np,nc,m,map[N][N],dis[N],gap[N]; 7 int s,e,w;//起点、终点、权值 8 char temp[20]; 9 int dfs(int src,int aug) 10 { 11 if(src==n+1)return aug; 12 int flow=0,min_d=n+1; 13 for(int i=0;i<=n+1;i++) 14 { 15 if(map[src][i]) 16 { 17 if(dis[src]==dis[i]+1) 18 { 19 int t=dfs(i,min(aug-flow,map[src][i])); 20 map[src][i]-=t; 21 map[i][src]+=t; 22 flow+=t; 23 if(aug==flow)break; 24 } 25 min_d=min(min_d,dis[i]); 26 } 27 } 28 if(!flow) 29 { 30 if(!(gap[dis[src]]--))dis[n]=n+2; 31 ++gap[dis[src]=min_d+1]; 32 } 33 return flow; 34 } 35 int main() 36 { 37 while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) 38 { 39 for(int i=0;i<=n+1;i++) 40 for(int j=0;j<=n+1;j++) 41 map[i][j]=0; 42 while(m--) 43 { 44 scanf("%s",temp); 45 int i=1,len=strlen(temp); 46 s=e=w=0; 47 while(temp[i]!=','){s=s*10+temp[i]-'0';i++;}i++; 48 while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;}i++; 49 while(i<len){w=w*10+temp[i]-'0';i++;} 50 map[s][e]+=w; 51 } 52 while(np--) 53 { 54 scanf("%s",temp); 55 int i=1,len=strlen(temp); 56 s=w=0; 57 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++; 58 while(i<len){w=w*10+temp[i]-'0';i++;} 59 map[n][s]+=w; 60 } 61 while(nc--) 62 { 63 scanf("%s",temp); 64 int i=1,len=strlen(temp); 65 s=w=0; 66 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++; 67 while(i<len){w=w*10+temp[i]-'0';i++;} 68 map[s][n+1]=w; 69 } 70 int answer=0; 71 for(int i=0;i<=n+1;i++)dis[i]=gap[i]=0; 72 gap[0]=n+1; 73 while(dis[n]<=n+1)answer+=dfs(n,Inf); 74 printf("%d\n",answer); 75 } 76 return 0; 77 }
View Code
1 #include<iostream> 2 #define min(a,b) a<b?a:b 3 #define Inf 0x7fffffff 4 #define N 110 5 using namespace std; 6 int n,np,nc,m,map[N][N],dis[N],gap[N],answer; 7 int s,e,w;//起点、终点、权值 8 int back_flow[N],cur_arc[N],pre[N],neck[N]; 9 char temp[20]; 10 void bfs() 11 { 12 int cur_flow,flag,min_dis,temp,cur; 13 cur=n; 14 cur_flow=Inf; 15 neck[n]=n; 16 while(dis[n]<=n+1) 17 { 18 back_flow[cur]=cur_flow; 19 flag=0; 20 for(int i=cur_arc[cur];i<=n+1;i++) 21 { 22 if(map[cur][i]&&dis[cur]==dis[i]+1) 23 { 24 pre[i]=cur; 25 cur_arc[cur]=i; 26 flag=1; 27 if(map[cur][i]<cur_flow) 28 { 29 cur_flow=map[cur][i]; 30 neck[i]=cur; 31 } 32 else 33 { 34 neck[i]=neck[cur]; 35 } 36 cur=i; 37 if(cur==n+1) 38 { 39 answer+=cur_flow; 40 while(cur!=n) 41 { 42 map[pre[cur]][cur]-=cur_flow; 43 back_flow[cur]-=cur_flow; 44 map[cur][pre[cur]]+=cur_flow; 45 cur=pre[cur]; 46 } 47 cur=neck[cur]; 48 cur_flow=back_flow[cur]; 49 } 50 break; 51 } 52 } 53 if(flag)continue; 54 min_dis=n+1; 55 for(int i=0;i<=n+1;i++) 56 { 57 if(map[cur][i]&&dis[i]<min_dis) 58 { 59 min_dis=dis[i]; 60 temp=i; 61 } 62 } 63 cur_arc[cur]=temp; 64 gap[dis[cur]]--; 65 if(gap[dis[cur]]==0)break; 66 dis[cur]=min_dis+1; 67 gap[dis[cur]]++; 68 if(cur!=n) 69 { 70 cur=pre[cur]; 71 cur_flow=back_flow[cur]; 72 } 73 } 74 } 75 int main() 76 { 77 while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) 78 { 79 for(int i=0;i<=n+1;i++) 80 for(int j=0;j<=n+1;j++) 81 map[i][j]=0; 82 while(m--) 83 { 84 scanf("%s",temp); 85 int i=1,len=strlen(temp); 86 s=e=w=0; 87 while(temp[i]!=','){s=s*10+temp[i]-'0';i++;}i++; 88 while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;}i++; 89 while(i<len){w=w*10+temp[i]-'0';i++;} 90 map[s][e]+=w; 91 } 92 while(np--) 93 { 94 scanf("%s",temp); 95 int i=1,len=strlen(temp); 96 s=w=0; 97 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++; 98 while(i<len){w=w*10+temp[i]-'0';i++;} 99 map[n][s]+=w; 100 } 101 while(nc--) 102 { 103 scanf("%s",temp); 104 int i=1,len=strlen(temp); 105 s=w=0; 106 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++; 107 while(i<len){w=w*10+temp[i]-'0';i++;} 108 map[s][n+1]=w; 109 } 110 answer=0; 111 for(int i=0;i<=n+1;i++)cur_arc[i]=dis[i]=gap[i]=0; 112 gap[0]=n+2; 113 bfs(); 114 printf("%d\n",answer); 115 } 116 return 0; 117 }