[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;
}
posted @ 2025-04-09 15:39  JoeyJiang  阅读(6)  评论(0)    收藏  举报