社区讨论

Dinic TLE 8个点 ,萌新求调

P4313文理分科参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@lo7us236
此快照首次捕获于
2023/10/27 08:06
2 年前
此快照最后确认于
2023/10/27 08:06
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
int n,m,sum,opt;
int head[1000010],ver[10000010],nex[10000010],edge[10000010],tot;
const int mod=2008,INF=1e9;
int d[1000010],now[1000010];
const int dx[4]={0,0,-1,1};
const int dy[4]={1,-1,0,0};
int maxflow,s,t;
void add(int x,int y,int z)
{
	ver[++tot]=y,nex[tot]=head[x],edge[tot]=z,head[x]=tot;
	ver[++tot]=x,nex[tot]=head[y],edge[tot]=0,head[y]=tot;
}
int num(int x,int y)
{
	return (x-1)*m+y;
}
bool check(int x,int y)
{
	return x>=1&&x<=n&&y>=1&&y<=m;
}
void solve1(int x,int y)
{
	for(int i=0;i<4;i++)
	{
		int nowx=dx[i]+x,nowy=dy[i]+y;
		if(check(nowx,nowy))
		add(opt,num(nowx,nowy),INF);
	}
}
void solve2(int x,int y)
{
	for(int i=0;i<4;i++)
	{
		int nowx=dx[i]+x,nowy=dy[i]+y;
		if(check(nowx,nowy))
		add(num(nowx,nowy),opt,INF);
	}
}
queue<int>q;
bool bfs()
{
	memset(d,0,sizeof(d));
	while(q.size())q.pop();
	d[s]=1,now[s]=head[s];
	q.push(s);
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=nex[i])
		{
			int y=ver[i];
			if(!d[y]&&edge[i])
			{
				d[y]=d[x]+1;
				now[y]=head[y];
				q.push(y);
				if(y==t)return 1;
			}
			
		}
	}
	return 0;
}
int dinic(int x,int flow)
{
	if(x==t)return flow;
	int rest=flow;
	int i,k;
	for(i=now[x];i;i=nex[i])
	{
		int y=ver[i];
		if(edge[i]&&d[y]==d[x]+1)
		{
			k=dinic(y,min(rest,edge[i]));
			if(!k)d[y]=0;
			edge[i]-=k;
			edge[i^1]+=k;
			rest-=k;
		}
	}
	now[x]=i;
	return flow-rest;
}
int main()
{
	tot=1;
	scanf("%d%d",&n,&m);
	s=n*m+1,t=n*m+2,opt=n*m+2;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		int k;
		scanf("%d",&k);
		sum+=k;
		add(s,num(i,j),k);
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		int k;
		scanf("%d",&k);
		sum+=k;
		add(num(i,j),t,k);
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		int k;
		scanf("%d",&k);opt++;
		sum+=k;
		add(s,opt,k);
		add(opt,num(i,j),INF);
		solve1(i,j);
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		int k;
		scanf("%d",&k);opt++;
		sum+=k;
		add(opt,t,k);
		add(num(i,j),opt,INF);
		solve2(i,j);
	}
	int flow=0;
	while(bfs())
	while(flow=dinic(s,INF))maxflow+=flow;
	printf("%d\n",sum-maxflow);
	return 0;
} 

回复

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

正在加载回复...