题意 有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;
}