wgyhm @ 2021-01-05 20:04:27
这是我没有加当前弧优化的代码,耗时稳定在 100ms 以内:
#include<bits/stdc++.h>
#define maxn 1005
#define rg register
#define int long long
using namespace std;
inline void read(int &x){
int f=1;x=0;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
x*=f;
}//快读
int now[maxn],h[maxn],deep[maxn],head,s,t,n,m;
struct yyy{
int to,z,w;
inline void add(int x,int y,int W){
to=y;z=h[x];h[x]=head;w=W;
}
}a[100005];
queue<int>q;
inline bool bfs(void){
rg int i,x;
memset(deep,0,sizeof(deep));
q.push(s);deep[s]=1;
while (!q.empty()){
x=q.front();q.pop();
for (i=h[x];i;i=a[i].z)
if (a[i].w&&!deep[a[i].to]){
deep[a[i].to]=deep[x]+1;
q.push(a[i].to);
}
}
return deep[t];
}
inline int dfs(int x,int in){
rg int i,rest=in,sum;
if (x==t) return in;
for (i=h[x];i&&rest;i=a[i].z)
if (deep[a[i].to]==deep[x]+1&&a[i].w){
sum=dfs(a[i].to,min(rest,a[i].w));
if (!sum) deep[a[i].to]=0;
a[i].w-=sum;a[i^1].w+=sum;rest-=sum;
}
return in-rest;
}
inline int Dinic(void){
int ans=0;
while (bfs()) ans+=dfs(s,1e9);
return ans;
}
signed main(){
rg int i,x,y,z;head=1;
read(n);read(m);read(s);read(t);
while (m--){
read(x);read(y);read(z);
a[++head].add(x,y,z);
a[++head].add(y,x,0);
}
printf("%lld",Dinic());
return 0;
}
这是加了当前弧优化,照着《算法竞赛进阶指南》上改的,但是加了以后时间在 900~1000ms 不等。
#include<bits/stdc++.h>
#define maxn 505
#define rg register
#define int long long
#define put() putchar('\n')
using namespace std;
inline void read(int &x){
int f=1;x=0;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
x*=f;
}//快读
int now[maxn],h[maxn],deep[maxn],head,s,t,n,m;
struct yyy{
int to,z,w;
inline void add(int x,int y,int W){
to=y;z=h[x];h[x]=head;w=W;
}
}a[100005];
queue<int>q;
inline bool bfs(void){
memset(deep,0,sizeof(deep));
rg int i,x;deep[s]=1;q.push(s);
for (i=1;i<=n;i++) now[i]=h[i];
while (!q.empty()){
x=q.front();q.pop();
for (i=h[x];i;i=a[i].z)
if (!deep[a[i].to]&&a[i].w){
deep[a[i].to]=deep[x]+1;
q.push(a[i].to);
}
}
return deep[t];
}
inline int dfs(int x,int in){
if (x==t||!in) return in;
rg int rest=in,i,sum;
for (i=now[x];i&&rest;i=a[i].z)
if (a[i].w&&deep[a[i].to]==deep[x]+1){
sum=dfs(a[i].to,min(rest,a[i].w));
if (!sum) deep[a[i].to]=0;
a[i].w-=sum;a[i^1].w+=sum;rest-=sum;
}
now[x]=a[i].z;//当前弧优化
return in-rest;
}
inline int Dinic(void){
rg int ans=0,in;
while (bfs()) ans+=dfs(s,1e18);
return ans;
}
signed main(){
rg int i,x,y,z;head=1;
read(n);read(m);read(s);read(t);
while (m--){
read(x);read(y);read(z);
a[++head].add(x,y,z);
a[++head].add(y,x,0);
}
printf("%lld",Dinic());
return 0;
}
请问我的当前弧优化哪里写假了?
还是我加的就是一个假的当前弧优化?
或者说是数据无意就使我的代码这么慢?
调了一个月了,求大佬解答。
by BlankAo @ 2021-01-05 20:25:53
for (i=now[x];i&&rest;i=a[i].z){
now[x]=i;
if (a[i].w&&deep[a[i].to]==deep[x]+1){
sum=dfs(a[i].to,min(rest,a[i].w));
if (!sum) deep[a[i].to]=0;
a[i].w-=sum;a[i^1].w+=sum;rest-=sum;
}
}
by BlankAo @ 2021-01-05 20:27:05
外面的now[x]=a[i].z;就去掉
by BlankAo @ 2021-01-05 20:27:32
@违规用户名FkZyA0!2
by cbio @ 2021-01-05 20:28:11
考虑一种情况,当一条边流出将rest用尽的话,这样写会直接跳过它,而不是下次再尝试流出
by wgyhm @ 2021-01-05 20:30:54
@BlankAo 按照您的写法为什么就可以啊?我觉得是等价的,但是您的写法就是快很多。。。
by wgyhm @ 2021-01-05 20:33:27
@cbio 我理解了,谢谢
by wgyhm @ 2021-01-05 20:33:56
此贴终结,感谢上面两位大佬
by zimujun @ 2021-01-07 18:09:33
@违规用户名FkZyA0!2 蓝书上的当前弧优化是假的
by wgyhm @ 2021-01-07 18:31:15
@zimujunqwq az