题意
树上删边游戏。。
在最后每一个叶子可能会挂上一个环
题解
首先,你要知道树上删边游戏的结论
然后套一个环的话
我们知道,如果是一个偶环
那么随意删掉一条边以后,剩下的奇偶性肯定一样
所以把他看做一个点即可
如果是奇环,则看做是一条边
然后就可以了
注意一下两个点的环,也就是重边
如果有奇数和重边,那么就不管他
如果是偶数个,那么就按偶环来算
CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1005;
int n,m,T;
struct qq
{
int x,y,last;
}e[N];int num,last[N];
void init (int x,int y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
bool vis[N];
int dfn[N],low[N],sta[N],top,id;
int mp[105][105];//处理重边
void dfs (int x,int fa)
{
sta[++top]=x;
dfn[x]=low[x]=++id;
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==fa)
{
if (mp[x][y]%2==0)vis[x]=true;
continue;
}
if (dfn[y]==-1)
{
dfs(y,x);
low[x]=min(low[x],low[y]);
}
else low[x]=min(low[x],dfn[y]);
}
if (low[x]==dfn[x])
{
int i=sta[top];
int lalal=0;
while (i!=x)
{
lalal++;
vis[i]=true;
i=sta[--top];
}
if (lalal!=0&&(lalal%2==0))//如果这是一个奇环,那么要保留
vis[sta[top+1]]=false;
top--;
}
}
int SG (int x,int fa)
{
int lalal=0;
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (vis[y]||y==fa) continue;
lalal=lalal^(1+SG(y,x));
}
return lalal;
}
int main()
{
while (scanf("%d",&T)!=EOF)
{
int ans=0;
while (T--)
{
memset(mp,0,sizeof(mp));
memset(vis,false,sizeof(vis));
num=0;memset(last,-1,sizeof(last));
memset(dfn,-1,sizeof(dfn));
top=id=0;
scanf("%d%d",&n,&m);
for (int u=1;u<=m;u++)
{
int x,y;
scanf("%d%d",&x,&y);
mp[x][y]++;mp[y][x]++;
init(x,y);init(y,x);
}
dfs(1,-1);
ans=ans^SG(1,-1);
}
if (ans>1) printf("Sally\n");
else printf("Harry\n");
}
return 0;
}