社区讨论

关于网络流,玄关

学术版参与者 3已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@mjsb067p
此快照首次捕获于
2025/12/30 16:06
2 个月前
此快照最后确认于
2026/01/02 13:00
2 个月前
查看原帖
之前没发现这个问题,直到这次做了两道网络流的题,发现开着long long会T,意识到严重性了。
我的代码:
CPP
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define pii pair<int,int>
#define il inline
#define re register
#define fs first
#define sc second
using namespace std;
il int read()
{
	re int x=0;
	re int ff=1;
	re char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')
			ff=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*ff;
}
const int N=3e3+6;
struct edge{
	int v,next,f;
};
edge e[N*N];
int n,sum,m,k,head[N],cur[N],dep[N];
il void add(re int u,re int v,re int w)
{
	e[k]={v,head[u],w},head[u]=k++;
	e[k]={u,head[v],0},head[v]=k++;
	(w!=1e12?sum+=w:0);return;
}
il bool bfs()
{
	memcpy(cur,head,sizeof(cur));
	memset(dep,0,sizeof(dep));
	queue<int> q;q.push(0),dep[0]=1;
	while(!q.empty()){
		re int u=q.front();q.pop();
		for(re int i=head[u],v;~i;i=e[i].next)
			if(!dep[v=e[i].v]&&e[i].f)
				dep[v]=dep[u]+1,q.push(v);
	}return dep[n+1];
}
il int dfs(re int u,re int cp)
{
	if(u==n+1)return cp;
	re int awa=cp;
	for(re int &i=cur[u],v;~i&&awa;i=e[i].next)
		if(dep[v=e[i].v]==dep[u]+1&&e[i].f){
			re int k=dfs(v,min(awa,e[i].f));
			if(!k)dep[v]=0;e[i].f-=k,e[i^1].f+=k,awa-=k;
		}return cp-awa;
}
il int dinic()
{
	re int awa=0;
	while(bfs())
		awa+=dfs(0,1e18);
	return awa;
}
signed main()
{memset(head,-1,sizeof(head));
	n=read(); 
	for(re int i=1;i<=n;i++)
		add(0,i,read());
	for(re int i=1;i<=n;i++)
		add(i,n+1,read());
	m=read();
	re int cnt=n+1;
	for(re int i=1;i<=m;i++){
		re int q=read();
		add(0,++cnt,read());
		add(++cnt,n+1,read());
		for(re int j=1,x;j<=q;j++)
			x=read(),add(cnt-1,x,1e12),add(x,cnt,1e12);
	}
	printf("%lld\n",sum-dinic());
	return 0;
}
别人一样的dinic跑了400ms左右,我的跑了3.8s。没有看懂问题出在哪里。
我的第一发代码
CPP
#include<bits/stdc++.h>
#define pb push_back
#define il inline
#define re register
#define pii pair<int,int>
#define fs first
#define sc second
using namespace std;
il int read()
{
	re int x=0;
	re int ff=1;
	re char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')
			ff=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*ff;
}
const int N=5e4+6;
const int M=3e5+6;
const int inf=1e6;
struct edge{
	int v,next,f;
};
edge e[M];
int n,m,k,head[N],cur[N],dep[N],id[106][106],s,t,sum;
il void add(re int u,re int v,re int w){(w^inf?sum+=w:0),e[k]={v,head[u],w},head[u]=k;e[++k]={u,head[v],0},head[v]=k++;return;}
il bool bfs(){memset(dep,0,sizeof(dep));queue<int> q;q.push(s),dep[s]=1,cur[s]=head[s];while(!q.empty()){re int u=q.front();q.pop();
for(re int i=head[u],v;~i;i=e[i].next)if(!dep[v=e[i].v]&&e[i].f)cur[v]=head[v],dep[v]=dep[u]+1,q.push(v);}return dep[t];}
il int dfs(re int u,re int cp){if(u==t)return cp;re int awa=cp;for(re int &i=cur[u],v;~i&&awa;i=e[i].next)
if(dep[v=e[i].v]==dep[u]+1&&e[i].f){re int k=dfs(v,min(awa,e[i].f));if(!k)dep[v]=0;e[i].f-=k,e[i^1].f+=k,awa-=k;}return cp-awa;}
il int dinic(){re int awa=0;while(bfs())awa+=dfs(s,1e9);return awa;}
signed main()
{memset(head,-1,sizeof(head));re int cnt=0;n=read(),m=read();s=0,t=n*m+1;
	for(re int i=1;i<=n;i++)for(re int j=1;j<=m;j++)id[i][j]=++cnt,add(s,cnt,read());
	for(re int i=1;i<=n;i++)for(re int j=1;j<=m;j++)add(id[i][j],t,read());cnt++;
	for(re int i=1;i<n;i++)for(re int j=1;j<=m;j++)add(s,++cnt,read()),add(cnt,id[i][j],inf),add(cnt,id[i+1][j],inf);
	for(re int i=1;i<n;i++)for(re int j=1;j<=m;j++)add(++cnt,t,read()),add(id[i][j],cnt,inf),add(id[i+1][j],cnt,inf);
	for(re int i=1;i<=n;i++)for(re int j=1;j<m;j++)add(s,++cnt,read()),add(cnt,id[i][j],inf),add(cnt,id[i][j+1],inf);
	for(re int i=1;i<=n;i++)for(re int j=1;j<m;j++)add(++cnt,t,read()),add(id[i][j],cnt,inf),add(id[i][j+1],cnt,inf);
	printf("%d\n",sum-dinic());return 0;
}
#define int long long的情况下T了,关了long long后跑了7s,别人的dinic只跑了200ms-300ms,神奇!
然后我去问了下AI,AI选择把我的压缩代码用AI的码风重新写一遍,结果它的代码只跑了1.5s!然后经过我的发现,dfs循环语句的退出条件~i&&awa改成循环中加上if(!awa)break;,原本跑了7s的代码只跑了1.6s!
请问各位大佬能解释一下这是为什么呢?顺便能看看我的dinic除了这个问题以外还有什么需要改进的呢?感谢,玄关。

回复

5 条回复,欢迎继续交流。

正在加载回复...