网络流的推送-重贴标签算法代码
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 struct pointtype{
5 int e;
6 int h;
7 }point[1001];
8 int map[1001][1001];
9 int c[1001][1001];
10 int n,m,s,t;
11 void init(int x){
12 for(int i=1;i<=n;i++){
13 point[i].h=0;
14 point[i].e=0;
15 }
16 point[s].h=n;
17 for(int i=1;i<=n;i++)
18 if(map[s][i]){
19 c[s][i]=map[s][i];
20 point[i].e+=map[s][i];
21 point[s].e-=map[s][i];
22 map[s][i]-=c[s][i];
23 map[i][s]+=c[s][i];
24 }
25 return;
26 }
27 bool check(){
28 for(int i=1;i<=n;i++)
29 if(point[i].e>0&&i!=t)
30 return true;
31 return false;
32 }
33 bool push(int x)
34 {
35 bool flag=false;
36 for(int i=1;i<=n;i++)
37 if(map[x][i]&&point[x].h==point[i].h+1){
38 int delta=min(point[x].e,map[x][i]);
39 map[x][i]-=delta;
40 map[i][x]+=delta;
41 point[x].e-=delta;
42 point[i].e+=delta;
43 flag=true;
44 }
45 return flag;
46 }
47 void change(int x){
48 int res=INT_MAX;
49 for(int i=1;i<=n;i++)
50 if(map[x][i])
51 res=min(res,point[i].h);
52 if(res==INT_MAX)
53 res-=1;
54 point[x].h=res+1;
55 return;
56 }
57 int main(){
58 cin>>n>>m;
59 for(int i=1;i<=n;i++)
60 for(int j=1;j<=n;j++){
61 map[i][j]=0;
62 c[i][j]=0;
63 }
64 for(int i=1;i<=m;i++){
65 int x,y,z;
66 cin>>x>>y>>z;
67 map[x][y]=z;
68 }
69 cin>>s>>t;
70 init(s);
71 while(check())
72 for(int i=1;i<=n;i++)
73 if(point[i].e>0)
74 if(!push(i)){
75 change(i);
76 point[t].h=0;
77 }
78 cout<<point[t].e<<endl;
79 return 0;
80 }