题目大意:
有N 个局部联通的图。
Harry 和Sally 轮流从图中删边,删去一条边后,不与根节点相连的部分将被移走。Sally 为先手。
图是通过从基础树中加一些边得到的。
所有形成的环保证不共用边,且只与基础树有一个公共点。
谁无路可走谁输。
输入
多组数据
每组数据第一行m和k表示m个节点,k条边,1为根节点
接下来k行描述边
输出
对于每组数据输出谁必胜
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1001
using namespace std;
int n,m,cnt,t,to[N],next[N],head[N],w[N],s[N],top;
int vis[N],ve[N];
void insert(int u,int v)
{
to[++cnt]=v;next[cnt]=head[u];head[u]=cnt;
to[++cnt]=u;next[cnt]=head[v];head[v]=cnt;
}
int dfs(int x)
{
vis[x]=1;
int ans=0;
s[++top]=x;
for(int i=head[x];i;i=next[i])
if(!ve[i])
{
ve[i]=1;ve[i^1]=1;
int temp;
if(!vis[to[i]])
temp=dfs(to[i])+1;
else
{
int q=s[top--];
while(q!=to[i])
{
w[q]=1;
q=s[top--];
}
++top;
return 1;
}
if(w[to[i]])
ans^=(temp)%2;
else
ans^=temp;
}
return ans;
}
int main()
{
while(scanf("%d",&t)!=EOF)
{
int ans=0;
while(t--)
{
memset(head,0,sizeof(head));
memset(next,-1,sizeof(next));
memset(vis,0,sizeof(vis));
memset(ve,0,sizeof(ve));
memset(w,0,sizeof(w));
top=0;
cnt=1;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
insert(x,y);
}
ans^=dfs(1);
}
if(ans)
printf("Sally\n");
else
printf("Harry\n");
}
return 0;
}