1. 程式人生 > >Christmas Game POJ - 3710

Christmas Game POJ - 3710

Christmas Game POJ - 3710

  1. 無向圖縮環變樹
  2. 樹刪邊博弈
    邊連通分量縮成一個點
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<cmath>
#define
mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar)) #define lowbit(x) (x&(-x)) #define Pb push_back #define FI first #define SE second #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define IOS ios::sync_with_stdio(false) #define
DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std; typedef long long LL; typedef unsigned long long ULL; const int prime = 999983; const int INF = 0x7FFFFFFF; const LL INFF =0x7FFFFFFFFFFFFFFF; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-6
; const LL mod = 1e9 + 7; LL qpow(LL a,LL b){LL s=1;while(b>0){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}return s;} LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;} int dr[2][4] = {1,-1,0,0,0,0,-1,1}; typedef pair<int,int> P; // 邊連通分量 vector<P> edges; const int maxn = 1e6+100; int pre[maxn]; int dfs_clock = 0; vector<int> G[maxn]; vector<int> G2[maxn]; int low[maxn]; // int father[maxn]; bool vis[maxn]; int belong[maxn]; int num[maxn]; void init(int m){ dfs_clock = 0; rep(i,1,m+1) G[i].clear(),G2[i].clear(); // me(low); memset(low,0,sizeof(low[0])*(m+1)); // me(pre); memset(pre,0,sizeof(pre[0])*(m+1)); // me(vis); memset(vis,0,sizeof(vis[0])*(m+1)); // me(num); memset(num,0,sizeof(num[0])*(m+1)); // me(belong); memset(belong,0,sizeof(belong[0])*(m+1)); } int dfs1(int u,int fa){ father[u] = fa; int lowu = pre[u] = ++dfs_clock; // int child = 0; int tofa = 0; for(int i = 0;i < (int)G[u].size(); ++i){ int v = G[u][i]; if(!pre[v]){ int lowv = dfs1(v,u); lowu = min(lowu,lowv); } else if( v != fa){ lowu = min(lowu,pre[v]); } else if(v == fa) { if(tofa) lowu = min(lowu,pre[v]); tofa++; } } return low[u] = lowu; } // #define Debug bool Is_bridge(int u,int v){ if(father[v] != u&&father[u] != v) return 0; return (pre[v] == low[v]); } void dfs(int u,int be){ belong[u] = be; for(int i = 0;i < (int)G[u].size(); ++i){ int v = G[u][i]; if(belong[v]) continue; if(Is_bridge(u,v)) continue; // cout<<u<<" "<<v<<endl; dfs(v,be); } } int SG(int u,int fa){ vis[u] = 1; int t = 0; for(int i = 0;i < (int)G2[u].size(); ++i){ int v = G2[u][i]; if(vis[v]) continue; t ^= (SG(v,u)+1); } if(num[u]&1) t ^= 1; return t; } int main(void) { // freopen("input.txt","r",stdin); // freopen("out.txt","w+",stdout); int n,m,k; // while(cin>>n){ cin>>n; while(n--){ int sum = 0; edges.clear(); scanf("%d%d",&m,&k); init(m); // cout<<m<<" "<<k<<endl; rep(i,0,k){ int u,v; scanf("%d%d",&u,&v); G[u].Pb(v); G[v].Pb(u); edges.Pb(P(u,v)); } // DEBUG // cout<<endl; dfs1(1,-1); int tot = 0; rep(i,1,m+1) if(!belong[i]) dfs(i,++tot); // cout<<en // cout<<tot<<endl; // dfs(m+1,) // DEBUG; for(int i = 0;i < (int)edges.size(); i ++){ int x = belong[edges[i].first]; int y = belong[edges[i].second]; if(x != y) G2[x].Pb(y),G2[y].Pb(x); else num[x]++; } // DEBUG; sum ^= SG(1,-1); // cout<<sum<<endl; // if (sum) cout << "Alice\n"; else cout << "Bob\n"; } // } return 0; }