博弈论 [ARC105E] Keep Graph Disconnected

21 篇文章 0 订阅
1 篇文章 0 订阅

紫题

洛谷题面 // AT原题题面

博弈好题。同样博弈的还有 ARC105D
敢情是博弈赛

题目大意:有一张 n n n 个点 m m m 条边的无向图,两人轮流添边,要求不能添加重边或形成自环,且点 1 1 1 和点 n n n 不能联通。先不能添边者输,问先后手胜败情况。

第一眼挺复杂的,显然像是博弈题,观察结局情况,易得由两个分别包含 1 1 1 号、 n n n 号的完全图构成。

先后手的输赢与奇偶性有关,讨论 n n n 的奇偶性。

n n n 为奇数时,最后分成的两个连通块一奇一偶,两个连通块的点数分别设为 s z i sz_i szi s z j sz_j szj,此时相对于 n n n 个点的完全图来说少了 s z i × s z j sz_i \times sz_j szi×szj 即偶数条边,共可添加 n × ( n − 1 ) / 2 − m − s z i × s z j n\times(n-1)/2-m-sz_i\times sz_j n×(n1)/2mszi×szj 条边,判断该式奇偶性即可。

n n n 为偶数时,类似的分析,发现最后的两个连通块可以是两个 s z sz sz 均为奇或均为偶,则共可添加边数为 n × ( n − 1 ) / 2 − m − s z i × s z j n\times(n-1)/2-m-sz_i\times sz_j n×(n1)/2mszi×szj,观察式子,可知式子的奇偶性与 s z i × s z j sz_i\times sz_j szi×szj 有关。注意下面的内容都在 n n n 为偶数的前提之下。

这时题目好像遇到了瓶颈,麻烦在于我们很难直接判断 s z i × s z j sz_i\times sz_j szi×szj 的奇偶性从而判断最后的必胜 / 败情况。

这同样是这题的突破口,因为如果最终存在必胜 / 败策略,那么必定可以推出一种方法,使得一定可由游戏开始导向一个 s z i × s z j sz_i\times sz_j szi×szj 的奇偶性确定的结局。

也就是说,最终 s z i × s z j sz_i\times sz_j szi×szj 的奇偶性即玩家胜败情况,在游戏刚开始时就是确定的 (废话

我们假设游戏开始时 1 1 1 号所在连通块的点数为 s z a sz_a sza n n n 号所在连通块的点数为 s z b sz_b szb

容易想到,游戏开始时,只有将连通块连接起来才能改变最终两个连通块的奇偶性,改变最终奇偶性从而才能改变结局。然后当只剩下两个连通块后双方只能再将两个连通块分别连成完全图。游戏结束。

分析一下 s z a sz_a sza s z b sz_b szb 的奇偶性,当 s z a sz_a sza s z b sz_b szb 是一奇一偶时,此时场上一定剩余了奇数个 s z sz sz 为奇数的连通块。可以发现,此时先手可以操纵最终 s z a sz_a sza s z b sz_b szb 的奇偶性。简单说明一下:

如果先手想让最后的 s z a sz_a sza s z b sz_b szb 均为奇数,那么在游戏开始时,先手可以将 s z a sz_a sza s z b sz_b szb 中偶数的那一个与场上任意一个 s z sz sz 为奇数的连通块连通,这时场上还剩下偶数个 s z sz sz 为奇数的连通块,且 s z a sz_a sza s z b sz_b szb 均为奇数。往后每当后手将 s z a sz_a sza / s z b sz_b szb 与一个 s z sz sz 为奇数的连通块连通后,先手都可以通过将 s z a sz_a sza / s z b sz_b szb 与一个 s z sz sz 为奇数的连通块连通从而使场上保持在 s z a sz_a sza s z b sz_b szb 都为奇数的局面。

如果先手想让最后的 s z a sz_a sza s z b sz_b szb 均为偶数,与上面对应的,在游戏开始时,先手可以将 s z a sz_a sza s z b sz_b szb 中奇数的那一个与场上任意一个 s z sz sz 为奇数的连通块连通,这时场上还剩下偶数个 s z sz sz 为奇数的连通块,且 s z a sz_a sza s z b sz_b szb 偶数。往后每当后手将 s z a sz_a sza / s z b sz_b szb 与一个 s z sz sz 为奇数的连通块连通后,先手都可以通过将 s z a sz_a sza / s z b sz_b szb 与一个 s z sz sz 为奇数的连通块连通从而使场上保持在 s z a sz_a sza s z b sz_b szb 都为偶数的局面。

结论就很明显了:当 n n n 为偶数时,若 s z a + s z b sz_a+sz_b sza+szb 为奇数,那么先手必胜。

接下来讨论若游戏还没开始时 s z a + s z b sz_a+sz_b sza+szb 为偶数的必胜 / 败情况。

可以发现,此时双方都不敢轻易地改变 s z a sz_a sza s z b sz_b szb 的奇偶性,因为只要某方改变了 s z a sz_a sza s z b sz_b szb 的奇偶性,场上就变成了 s z a sz_a sza s z b sz_b szb一奇一偶的局面,由上面的结论: n n n 为偶数时,若 s z a + s z b sz_a+sz_b sza+szb 为奇数,那么先手必胜 可知,此时对手必胜。

所以双方都不会将 1 1 1 号所在的连通块或 n n n 号所在的连通块与其余 s z sz sz 为奇数的连通块连通,那么此时游戏策略只有两种:

1.将场上其余连通块互相连通

2.将 1 1 1 号或 n n n 号所在连通块与其余 s z sz sz 为偶数的连通块连通

而这两种策略都不会影响 1 1 1 号和 n n n 号所在连通块的奇偶性。

之前有一个问题想了很久: 如果按照场上开始 s z a sz_a sza s z b sz_b szb 的奇偶性本来一方能赢,会不会玩到该方最后无路可连,只能将一个奇数连通块连向 1 1 1 / n n n 所在连通块使得局面变成 s z a + s z b sz_a+sz_b sza+szb 为奇数、对方获胜?

实际是不会的,因为按照上面的游戏策略:

 1.将场上其余连通块互相连通
 2.将 $1$ 号或 $n$ 号所在连通块与其余 $sz$ 为偶数的连通块连通

最终除 1 1 1 n n n 所在连通块的所有连通块会连成一个大连通块,而该连通块的 s z sz sz 为偶数,因为如题 s z a + s z b sz_a+sz_b sza+szb 为偶数。

结论就得出了:若游戏还没开始时 s z a + s z b sz_a+sz_b sza+szb 为偶数,则游戏过程中 s z a sz_a sza s z b sz_b szb 的奇偶性保持不变,通过 n × ( n − 1 ) / 2 − m − s z i × s z j n\times(n-1)/2-m-sz_i\times sz_j n×(n1)/2mszi×szj 可得必胜败情况。

讲得是不是过详细了

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+5;
LL n,m;
int t,vis[N],p[N];
struct qh{
	int v,nt;
}E[N<<1];
void add(int u,int v){E[++p[0]]=(qh){v,p[u]};p[u]=p[0];return ;}
inline int Rd(){
	int s=0,w=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
	return s*w;
}
void dfs(int x){
	t++;
	vis[x]=1;
	for(int i=p[x];i;i=E[i].nt){
		int v=E[i].v;
		if(!vis[v]) dfs(v);
	}
	return ;
}
int main(){
	int T=Rd();
	while (T--){
		memset(vis,0,sizeof(vis));
		memset(p,0,sizeof(p));
		n=Rd();m=Rd();
		for(int i=1;i<=m;i++){
			int x=Rd(),y=Rd();
			add(x,y);add(y,x);
		}
		LL s=(n-1)*n/2ll-m;
		if(n&1ll){
			if(s&1ll) puts("First");
			else puts("Second");
		}
		else{
			int t2,t1;t=0;
			dfs(1);t1=t;
			dfs(n);t2=t-t1;
			if((t1+t2)&1) puts("First");
			else{
				if((t1&1)&&(t2&1)){
					if(s&1) puts("Second");
					else puts("First");
				}
				else{
					if(s&1) puts("First");
					else puts("Second");
				}
			}
		}
	}
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值