poj 3710

题意

树上删边游戏。。
在最后每一个叶子可能会挂上一个环

题解

首先,你要知道树上删边游戏的结论
S G [ x ] = ( S G [ s 1 ] + 1 ) x o r ( S G [ s 2 ] + 1 ) x o r ( S G [ s 3 ] + 1 ) . . . .
然后套一个环的话
我们知道,如果是一个偶环
那么随意删掉一条边以后,剩下的奇偶性肯定一样
所以把他看做一个点即可
如果是奇环,则看做是一条边
然后就可以了
注意一下两个点的环,也就是重边
如果有奇数和重边,那么就不管他
如果是偶数个,那么就按偶环来算
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;
}

猜你喜欢

转载自blog.csdn.net/qq_36797743/article/details/80103080