2023 ICPC Gran Premio de Mexico 1ra Fecha

K Kingdom Power C.

题意 有n个关卡,给你s个开始关卡,E个结束关卡,然后从开始关卡开始,结束关卡结束,有的关卡必须完成前一个关卡才能开始,开始关卡可以直接开始,问你如何运行游戏最大数量 运行一次游戏指 从开始关卡到结束关卡 。然后游戏结束后,之前玩的关卡都不能再玩了。

题解:网络流模板变形题,根据题目意思变形建边,求一下最大流

至于如何建图,首先先拆点,将一个点拆成俩点为2*x,2*x+1,如果是开始关卡前面与S点相连,是结束关卡2*x+1与t相连,然后将这俩点相连,然后根据流向的顺序再建立里面的边

# include <bits/stdc++.h>
using namespace std;
# define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
int n,m,s,t;
const int N=50010;
const int M=300010;
int book[N]; 
int head[N],ver[M],edge[M],Next[M],d[N];
int now[N];
queue<int>q;
int tot=1;
const int inf=1<<29;
int maxflow=0;
void add(int x,int y,int z)
{
	ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
	ver[++tot]=x,edge[tot]=0,Next[tot]=head[y],head[y]=tot;
}
bool bfs()
{
	memset(d,0,sizeof(d));
	while(q.size())
	{
		q.pop();
	}
	q.push(s);
	d[s]=1;
	now[s]=head[s];
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(int i=head[x]; i; i=Next[i])
		{
			if(edge[i]&&!d[ver[i]])
			{
				q.push(ver[i]);
				now[ver[i]]=head[ver[i]];
				d[ver[i]]=d[x]+1;
				if(ver[i]==t)
				{
					return 1;
				}
			}
		}
	}
	return 0;
}
int dinic(int x,int flow)
{
	if(x==t)
	{
		return flow;
	}
	int rest=flow,k,i;
	for(i=now[x]; i&&rest; i=Next[i])
	{
		now[x]=i;
		if(edge[i]&&d[ver[i]]==d[x]+1)
		{
			k=dinic(ver[i],min(rest,edge[i]));
			if(!k)
			{
				d[ver[i]]=0;
			}
			edge[i]-=k;
			edge[i^1]+=k;
			rest-=k;
		}
	}
	return flow-rest;
}
signed main()
{
	IOS
	int S,E;
	cin>>n>>S>>E;
	s=1;
	t=2*n+4;
	for(int i=1; i<=S; i++)
	{
		int x;
		cin>>x;
		x++;
		add(1,2*x,1);
	}
	for(int i=2; i<=n+1; i++)
	{
        add(2*i,2*i+1,1);
	}
	for(int i=1; i<=E; i++)
	{
		int x;
		cin>>x;
		x++;
		add(2*x+1,t,1);
	}
	cin>>m;
	for(int i=1; i<=m; i++)
	{
		int x,y;
		cin>>x>>y;
		x++;
		y++;
		if(book[x])
		{
			continue ;
		}
		add(2*x+1,2*y,1);
        
	}
	int flow=0;
	while(bfs())
	{
		while(flow=dinic(s,inf))
		{
			maxflow+=flow;
		}
	}
	cout<<maxflow<<endl;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值