study from :
https://www.luogu.org/blog/top-oier/qian-tan-you-shang-xia-jie-di-wang-lao-liu
网络流
每次都要对dep数组进行初始化。
dfs函数的优化:如果TLE,尝试使用一下。
loj
https://loj.ac/problem/115
115
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <queue> 10 #include <iostream> 11 using namespace std; 12 13 #define ll long long 14 15 const int maxn=2e2+10; 16 const int maxm=10201; 17 const int inf=1e9; 18 const double eps=1e-8; 19 20 struct node 21 { 22 int d,len; 23 node *to,*opp; 24 }*e[maxn],*b[maxm]; 25 26 int dif[maxn],dep[maxn],q[maxn],n,low[maxm],ss,tt,st,en; 27 28 void addedge(int x,int y,int z) 29 { 30 node *p1,*p2; 31 p1=new node(); 32 p2=new node(); 33 34 p1->d=y; 35 p1->len=z; 36 p1->to=e[x]; 37 p1->opp=p2; 38 e[x]=p1; 39 40 p2->d=x; 41 p2->len=0; 42 p2->to=e[y]; 43 p2->opp=p1; 44 e[y]=p2; 45 } 46 47 void addedge_1(int x,int y,int z,int i) 48 { 49 node *p1,*p2; 50 p1=new node(); 51 p2=new node(); 52 53 p1->d=y; 54 p1->len=z; 55 p1->to=e[x]; 56 p1->opp=p2; 57 e[x]=p1; 58 59 p2->d=x; 60 p2->len=0; 61 p2->to=e[y]; 62 p2->opp=p1; 63 e[y]=p2; 64 65 b[i]=p2; 66 } 67 68 bool bfs() 69 { 70 node *p; 71 int head=0,tail=1,d,dd; 72 memset(dep,0,sizeof(dep)); 73 dep[st]=1; 74 q[1]=st; 75 while (head<tail) 76 { 77 head++; 78 d=q[head]; 79 p=e[d]; 80 while (p) 81 { 82 dd=p->d; 83 if (!dep[dd] && p->len) 84 { 85 q[++tail]=dd; 86 dep[dd]=dep[d]+1; 87 } 88 p=p->to; 89 } 90 } 91 if (dep[en]) 92 return 1; 93 return 0; 94 } 95 96 int dfs(int d,int add) 97 { 98 if (!add || d==en) 99 return add; 100 int totr=0,r,dd; 101 node *p=e[d]; 102 while (p) 103 { 104 dd=p->d; 105 if (dep[dd]==dep[d]+1 && (r=dfs(dd,min(add,p->len)))>0) 106 { 107 totr+=r; 108 add-=r; 109 p->len-=r; 110 p->opp->len+=r; 111 } 112 p=p->to; 113 } 114 return totr; 115 } 116 117 int main() 118 { 119 int m,x,y,u,v,tot=0,sum=0,i; 120 scanf("%d%d",&n,&m); 121 ss=0,tt=n+1; 122 st=ss,en=tt; 123 for (i=1;i<=m;i++) 124 { 125 scanf("%d%d%d%d",&x,&y,&u,&v); 126 low[i]=u; 127 dif[x]-=u,dif[y]+=u; 128 addedge_1(x,y,v-u,i); 129 } 130 for (i=1;i<=n;i++) 131 if (dif[i]>0) 132 { 133 addedge(ss,i,dif[i]); 134 tot+=dif[i]; 135 } 136 else 137 addedge(i,tt,-dif[i]); 138 139 while (bfs()) 140 sum+=dfs(st,inf); 141 if (sum==tot) 142 { 143 printf("YES "); 144 for (i=1;i<=m;i++) 145 printf("%d ",low[i]+b[i]->len); 146 } 147 else 148 printf("NO"); 149 return 0; 150 } 151 /* 152 153 */
116
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <queue> 10 #include <iostream> 11 using namespace std; 12 13 #define ll long long 14 15 const int maxn=2e2+10; 16 const int maxm=1e4; 17 const int inf=1e9; 18 const double eps=1e-8; 19 20 struct node 21 { 22 int d,len; 23 node *to,*opp; 24 }*e[maxn]; 25 26 int dif[maxn],dep[maxn],q[maxn],n,low[maxm],ss,tt,st,en; 27 28 void addedge(int x,int y,int z) 29 { 30 node *p1,*p2; 31 p1=new node(); 32 p2=new node(); 33 34 p1->d=y; 35 p1->len=z; 36 p1->to=e[x]; 37 p1->opp=p2; 38 e[x]=p1; 39 40 p2->d=x; 41 p2->len=0; 42 p2->to=e[y]; 43 p2->opp=p1; 44 e[y]=p2; 45 } 46 47 bool bfs() 48 { 49 node *p; 50 int head=0,tail=1,d,dd; 51 memset(dep,0,sizeof(dep)); 52 dep[st]=1; 53 q[1]=st; 54 while (head<tail) 55 { 56 head++; 57 d=q[head]; 58 p=e[d]; 59 while (p) 60 { 61 dd=p->d; 62 if (!dep[dd] && p->len) 63 { 64 q[++tail]=dd; 65 dep[dd]=dep[d]+1; 66 } 67 p=p->to; 68 } 69 } 70 if (dep[en]) 71 return 1; 72 return 0; 73 } 74 75 int dfs(int d,int add) 76 { 77 if (!add || d==en) 78 return add; 79 int totr=0,r,dd; 80 node *p=e[d]; 81 while (p) 82 { 83 dd=p->d; 84 if (dep[dd]==dep[d]+1 && (r=dfs(dd,min(add,p->len)))>0) 85 { 86 totr+=r; 87 add-=r; 88 p->len-=r; 89 p->opp->len+=r; 90 } 91 p=p->to; 92 } 93 return totr; 94 } 95 96 int main() 97 { 98 int m,s,t,x,y,u,v,tot=0,sum=0,i; 99 scanf("%d%d%d%d",&n,&m,&s,&t); 100 ss=0,tt=n+1; 101 for (i=1;i<=m;i++) 102 { 103 scanf("%d%d%d%d",&x,&y,&u,&v); 104 dif[x]-=u,dif[y]+=u; 105 addedge(x,y,v-u); 106 } 107 for (i=1;i<=n;i++) 108 if (dif[i]>0) 109 { 110 tot+=dif[i]; 111 addedge(ss,i,dif[i]); 112 } 113 else 114 addedge(i,tt,-dif[i]); 115 addedge(t,s,inf); 116 117 st=ss,en=tt; 118 while (bfs()) 119 sum+=dfs(st,inf); 120 if (sum==tot) 121 { 122 sum=0; 123 st=s,en=t; 124 while (bfs()) 125 sum+=dfs(st,inf); 126 printf("%d",sum); 127 } 128 else 129 printf("please go home to sleep"); 130 return 0; 131 } 132 /* 133 134 */
117
那个博客里解1的方法好像不对
dfs函数的两个优化,不知道是否真的有用。。。
95分,loj的第8个数据,dfs函数执行了很长时间。
看了一下其它代码,感觉是因为存储方式不一样,所以过了,感觉靠脸。。。
应该还有更好的优化方法,待学。
data 链接: https://pan.baidu.com/s/1BoxoTiTgYCaXcZcRisJz5Q 提取码: d3ip
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <queue> 10 #include <iostream> 11 using namespace std; 12 13 #define ll long long 14 15 const int maxn=50003+10; 16 const int maxm=125003+10; 17 const ll inf=1e18; 18 const double eps=1e-8; 19 20 struct node 21 { 22 int d; 23 ll len; 24 node *to,*opp; 25 }*e[maxn]; 26 27 ll dif[maxn],z=0; 28 int dep[maxn],q[maxn],n,ss,tt,st,en; 29 30 void addedge(int x,int y,ll z) 31 { 32 node *p1,*p2; 33 p1=new node(); 34 p2=new node(); 35 36 p1->d=y; 37 p1->len=z; 38 p1->to=e[x]; 39 p1->opp=p2; 40 e[x]=p1; 41 42 p2->d=x; 43 p2->len=0; 44 p2->to=e[y]; 45 p2->opp=p1; 46 e[y]=p2; 47 } 48 49 bool bfs() 50 { 51 node *p; 52 int head=0,tail=1,d,dd; 53 memset(dep,0,sizeof(dep)); 54 dep[st]=1; 55 q[1]=st; 56 while (head<tail) 57 { 58 head++; 59 d=q[head]; 60 p=e[d]; 61 while (p) 62 { 63 dd=p->d; 64 if (!dep[dd] && p->len) 65 { 66 q[++tail]=dd; 67 dep[dd]=dep[d]+1; 68 // if (dd==en) 69 // return 1; 70 } 71 p=p->to; 72 } 73 } 74 // if (dep[en]) 75 // return 1; 76 return 0; 77 } 78 79 ll dfs(int d,ll add) 80 { 81 z++; 82 if (!add || d==en) 83 return add; 84 int dd; 85 ll totr=0,r; 86 node *p=e[d]; 87 while (p) 88 { 89 dd=p->d; 90 if (dep[dd]==dep[d]+1 && (r=dfs(dd,min(add,p->len)))>0) 91 { 92 totr+=r; 93 add-=r; 94 p->len-=r; 95 p->opp->len+=r; 96 if (totr==add) 97 return totr; 98 } 99 p=p->to; 100 } 101 if (!totr) 102 dep[d]=-1; 103 return totr; 104 } 105 106 int main() 107 { 108 int m,s,t,x,y,i; 109 ll u,v; 110 ll tot=0,sum=0; 111 scanf("%d%d%d%d",&n,&m,&s,&t); 112 ss=0,tt=n+1; 113 for (i=1;i<=m;i++) 114 { 115 scanf("%d%d%lld%lld",&x,&y,&u,&v); 116 dif[x]-=u,dif[y]+=u; 117 addedge(x,y,v-u); 118 } 119 for (i=1;i<=n;i++) 120 if (dif[i]>0) 121 { 122 tot+=dif[i]; 123 addedge(ss,i,dif[i]); 124 } 125 else 126 addedge(i,tt,-dif[i]); 127 128 st=ss,en=tt; 129 while (bfs()) 130 sum+=dfs(st,inf); 131 132 addedge(t,s,inf); 133 while (bfs()) 134 sum+=dfs(st,inf); 135 136 printf("z=%lld ",z); 137 138 if (sum==tot) 139 printf("%lld",e[s]->len); 140 else 141 printf("please go home to sleep"); 142 return 0; 143 } 144 /* 145 146 */