树上删边游戏 (需要加上对于特殊环的处理)
由于至今还不理解Multi-SG的原理和树上SG转移值需要“+1”的原理,只会记住这样的公式,所以就不写思路了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
using namespace std;
const int N=101,M=501;
int T,n,m,u,v,ans,tot;
int sta[N];
bool vis[N],pd[N];
int cnt,head[N];
struct edge{int next,to; bool f;}e[M<<1];
inline void add(int u,int v)
{
cnt++;
e[cnt].next=head[u];
e[cnt].to=v;
e[cnt].f=false;
head[u]=cnt;
}
int dfs(int u)
{
int ans=0;
vis[u]=true; sta[++tot]=u;
for (register int i=head[u]; i; i=e[i].next)
if (!e[i].f)
{
e[i].f=e[i^1].f=true;
int now;
if (!vis[e[i].to]) now=dfs(e[i].to)+1;
else
{
while (sta[tot]!=e[i].to) pd[sta[tot]]=true,tot--;
return 1;
}
if (pd[e[i].to]) now&=1;
ans^=now;
}
return ans;
}
int main(){
while (~scanf("%d",&T))
{
ans=0;
while (T--)
{
cnt=1; memset(head,0,sizeof(head));
scanf("%d%d",&n,&m);
for (register int i=1; i<=m; ++i) scanf("%d%d",&u,&v),add(u,v),add(v,u);
memset(vis,false,sizeof(vis)); memset(pd,false,sizeof(pd));
tot=0;
ans^=dfs(1);
}
if (ans) puts("Sally");
else puts("Harry");
}
return 0;
}