[ARC105] E - Keep Graph Disconnected
题面
题目描述
定义一个点集大小为 \(n\) 的简单无向图 \(G\) 是好图当且仅当 \(G\) 中 \(1\) 和 \(n\) 不可达。
现给定一个好图 \(G=(V,E)\),其中 \(|V|=n,|E|=m\)。两名玩家依次轮流尝试向途中加入一条无向边,第一个不能操作的判为负,问最后胜者。
数据范围
- \(1\leq n,m\leq 10^5\)。
题解
显然最后的图一定是,由两个团构成的,其中一个包含 \(1\),另一个包含 \(n\)。
令 \(k\) 为包含 \(1\) 的团的大小,则总操作边数为 \(\frac {n(n-1)}2-k(n-k)-m\)。
-
当 \(n\) 是奇数时,\(k(n-k)\) 一定是偶数,则答案仅与 \(n\) 和 \(m\) 有关。
-
当 \(n\) 是偶数时,令 \(x\) 为 \(G\) 中包含 \(1\) 的连通块大小,\(y\) 为包含 \(n\) 的。
-
当 \(x\) 和 \(y\) 奇偶不同时,先手一定可以将 \(x\) 和 \(y\) 变为奇奇或者偶偶,并保持这个优势,所以先手必胜
-
当 \(x\) 和 \(y\) 奇偶相同时,奇连通块和偶连通块的数量均为偶数。先后手为了最优化一定会使 \(x\) 和 \(y\) 的奇偶性保持不变,于是直接拿初始的 \(x\) 做即可。
-
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=1e5+9;
int fa[N],siz[N],n,m;
inline int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
inline void Merge(int x,int y){
x=Find(x),y=Find(y);
if(x==y) return ;
fa[y]=x,siz[x]+=siz[y];
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
for(int i=1,u,v;i<=m;i++) cin>>u>>v,Merge(u,v);
int tmp=1ll*n*(n-1)/2&1;
if(n&1){
if((tmp^m)&1) cout<<"First"<<endl;
else cout<<"Second"<<endl;
}else{
int x=Find(1),y=Find(n);
if((siz[x]^siz[y])&1) cout<<"First"<<endl;
else{
if((tmp^m^siz[x])&1) cout<<"First"<<endl;
else cout<<"Second"<<endl;
}
}
}
return 0;
}