网络流救救孩子吧呜呜呜
查看原帖
网络流救救孩子吧呜呜呜
299810
issue_is_fw楼主2020/8/18 23:31

对于第一问我想的和题解差不多

不过我不是拆点

比如对于m=2,n=2时,图大概这个样子

但是因为不能经过同样的点,所以我这样

这样那个正方形后边的边流量为1

这样就限制了前两个点不能同时过来

请问这样有什么错误嘛emm

困扰了好久,救救孩子把

#include <bits/stdc++.h>
using namespace std;
const int inf=1e9;
const int maxn=2e5+10;
int m,n,s,t,a[209][209];
struct edge{
	int to,nxt,flow,w;
}d[maxn]; int head[maxn],cnt=1,top;
void add(int u,int v,int flow,int w){
	d[++cnt]=(edge){v,head[u],flow,w},head[u]=cnt;
	d[++cnt]=(edge){u,head[v],0,-w},head[v]=cnt;
}
int dis[maxn],pre[maxn],vis[maxn],flow[maxn];
bool spfa()
{
	for(int i=0;i<=top;i++)	dis[i]=-inf,vis[i]=0;
	queue<int>q; q.push( s );
	dis[s]=0;flow[s]=inf;
	while( !q.empty() )
	{
		int u=q.front(); q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=d[i].nxt )
		{
			int v=d[i].to;
			if( dis[v]<dis[u]+d[i].w&&d[i].flow )
			{
				dis[v]=dis[u]+d[i].w;
				pre[v]=i;
				flow[v]=min(flow[u],d[i].flow);
				if( !vis[v] )	vis[v]=1,q.push(v);
			}
		}
	}
	if( dis[t]!=-inf )	return true;
	return false;
}
int dinic()
{
	int maxcost=0;
	while( spfa() )
	{
		int x=t;
		maxcost+=flow[t]*dis[t];
		while( x!=s )
		{
			int i=pre[x];
			d[i].flow-=flow[t];
			d[i^1].flow+=flow[t];
			x=d[i^1].to;
		}
	}
	return maxcost;
}
int main()
{
	cin >> m >> n;
	s=0,t=m*n+n*(n-1)/2+1;
	top=t+1;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m+i-1;j++)
		cin >> a[i][j];
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m+i-1;j++)
	{
		int now=(i-1)*m+(i-1)*(i-2)/2+j;
		int xia=i*m+i*(i-1)/2+j;
		if( i==n )
		{
			add(now,t,1,0);
			continue;
		}
		if( j==1 )
		{
			add(now,xia,1,a[i+1][j] );
			add(now,++top,1,a[i+1][j+1] );	
		}
		else if( j==m+i-1 )
		{
			add(now,top,1,a[i+1][j]);
			add(now,xia+1,1,a[i+1][j+1] );
		}
		else
		{
			add(now,top,1,a[i+1][j] );
			add(top,xia,1,0);
			add(now,++top,1,a[i+1][j+1] );
		}
	}
	for(int i=1;i<=m;i++)	add(s,i,1,a[1][i]);
	cout << dinic();//第一问 
}
2020/8/18 23:31
加载中...