“蔚来杯“2022牛客暑期多校训练营10-F Shannon Switching Game?

原题题面:https://ac.nowcoder.com/acm/contest/33195/F

文章目录

  • 题目大意
  • 解题思路
  • 代码实现

题目大意

The Shannon switching game的变体规则如下:
给定可能有重边的无向图 G = ( V , E ) ( 1 ≤ ∣ V ∣ ≤ 100 , 1 ≤ ∣ E ∣ ≤ 10000 ) G=(V,E)(1\le|V|\le100,1\le |E|\le 10000) G=(V,E)(1V100,1E10000),和两个点 s , t ∈ V s,t\in V s,tV。最初在 d d d点上有一个令牌。两个玩家Join Player和Cut Player轮流进行以下操作,Cut Player先手:

  • 如果轮到Join Player,假如令牌在点 u u u,则选择边 ( u , v ) ∈ E (u,v)\in E (u,v)E,删除它并将令牌移动到点 v v v
  • 如果轮到Cut Player,假如令牌在点 u u u,则选择边 ( u , v ) ∈ E (u,v)\in E (u,v)E,删除它。
    当任意玩家无法进行操作时,游戏结束。
    如果令牌在游戏期间到达点 t t t,则Join Player获胜。反之Cut Player获胜。

假设双方均采用最优策略,给定图 G G G,求谁会获胜。

解题思路

考虑与 t t t相连的点能到达 t t t该满足什么条件,显然应保证至少有两条边连向 t t t,在考虑对于任意点 u u u,该如何保证到达能够到达 t t t的点,显然要保证至少有两条边连向能够到达 t t t的点。按时此思路跑一遍 B F S BFS BFS即可。

代码实现

#include
using namespace std;
int n,m,s,t;
int a[105][105],vis[105],cnt,dp[105];
void bfs(){
	queue<int>qu;
	qu.push(t);
	vis[t]++;
	while(!qu.empty()){
		int k=qu.front();
		qu.pop();
		for(int i=1;i<=n;i++){
			if(a[i][k]){
				dp[i]+=a[i][k];
				if(!vis[i]&&dp[i]>1){
					qu.push(i);
					vis[i]++;
				} 
			}
		}
	}
}
void solve(){
	cin>>n>>m>>s>>t;
	memset(a,0,sizeof(a));
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		a[u][v]++;
		a[v][u]++;
	}
	memset(vis,0,sizeof(vis));
	memset(dp,0,sizeof(dp));
	bfs();
	if(dp[s]>1){
		puts("Join Player");
		return;
	}
	puts("Cut Player");
}
int T;
int main(){
	cin>>T;
	while(T--)solve();
}

你可能感兴趣的:(多校联赛,“蔚来杯“,图论,算法,c++)