| 记录编号 |
103382 |
评测结果 |
AA |
| 题目名称 |
1648.[IPSC2003]到根了吗? |
最终得分 |
100 |
| 用户昵称 |
cstdio |
是否通过 |
通过 |
| 代码语言 |
C++ |
运行时间 |
0.127 s |
| 提交时间 |
2014-05-27 20:23:03 |
内存使用 |
3.27 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int SIZEN=50010;//点数范围,也是边数范围
int N,M;
int T;
class EDGE{
public:
int to;
int id;
};
vector<EDGE> c[SIZEN];
vector<int> tree[SIZEN];
pair<int,int> edges[SIZEN];
bool isbridge[SIZEN];
bool visit[SIZEN]={0};
int father[SIZEN]={0};//来的边,有重边的Tarjan真是一个奇怪的玩意......
int dfn[SIZEN]={0},low[SIZEN]={0};
int timer;
int tot;
int comp[SIZEN]={0};
int edgenum[SIZEN]={0};
int compsg[SIZEN]={0};
int SG[SIZEN]={0};
void Tarjan(int x){
visit[x]=true;//无向图没有横叉边
dfn[x]=low[x]=++timer;
for(int i=0;i<c[x].size();i++){
int v=c[x][i].to;
if(!visit[v]){
father[v]=c[x][i].id;
Tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(c[x][i].id!=father[x]) low[x]=min(low[x],dfn[v]);
if(dfn[x]<low[v]) isbridge[c[x][i].id]=true;
}
}
void DFS(int x){//给每个联通块标号
visit[x]=true;
comp[x]=tot;
for(int i=0;i<c[x].size();i++){
int v=c[x][i].to;
if(isbridge[c[x][i].id]||visit[v]) continue;
DFS(v);
}
}
void searchedge(void){//统计每块有多少边,顺便建树
for(int i=1;i<=M;i++){
int a=edges[i].first,b=edges[i].second;
if(!isbridge[i]&&comp[a]==comp[b]){
edgenum[comp[a]]++;
}
if(comp[a]!=comp[b]){
tree[comp[a]].push_back(comp[b]);
tree[comp[b]].push_back(comp[a]);
}
}
}
int DP(int x){
visit[x]=true;
int &ans=SG[x];
for(int i=0;i<tree[x].size();i++){
if(!visit[tree[x][i]]){
ans^=(DP(tree[x][i])+1);
}
else if(tree[x][i]==x) ans^=1;
}
return ans;
}
void work(void){
Tarjan(1);
memset(visit,0,sizeof(visit));
for(int i=1;i<=N;i++) if(!visit[i]) tot++,DFS(i);
searchedge();
for(int i=1;i<=tot;i++) SG[i]=edgenum[i]&1;//算了两次
memset(visit,0,sizeof(visit));
if(DP(comp[1])) printf("Alice\n");
else printf("Bob\n");
}
void globalclear(void){
for(int i=0;i<SIZEN;i++) c[i].clear();
for(int i=0;i<SIZEN;i++) tree[i].clear();
memset(isbridge,0,sizeof(isbridge));
timer=0;
tot=0;
memset(visit,0,sizeof(visit));
memset(edgenum,0,sizeof(edgenum));
memset(SG,0,sizeof(SG));
}
void read(void){
scanf("%d%d",&N,&M);
globalclear();
int a,b;
for(int i=1;i<=M;i++){
scanf("%d%d",&a,&b);
edges[i]=make_pair(a,b);
c[a].push_back((EDGE){b,i});
c[b].push_back((EDGE){a,i});
}
}
int main(){
freopen("gotroot.in","r",stdin);
freopen("gotroot.out","w",stdout);
scanf("%d",&T);
while(T--){
read();
work();
}
return 0;
}