poj3710 Christmas Game

题目描述

题解:

树上删边。

对于奇数长度的环,可以看做一条边。

对于偶数长度的环,可以看做什么都没有。

没有特别好的解释……

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 150;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch = getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int T,n,m,hed[N],cnt;
struct EG
{
    int to,nxt;
}e[10*N];
void ae(int f,int t)
{
    e[++cnt].to = t;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
bool vis[N],cir[N],ban[10*N];
int sta[N],tl;
int dfs(int u)
{
    vis[u]=1;
    sta[++tl]=u;
    int ret = 0;
    for(int j=hed[u];~j;j=e[j].nxt)
    {
        if(ban[j])continue;
        ban[j]=ban[j^1]=1;
        int to = e[j].to;
        int now;
        if(!vis[to])now=(dfs(to)+1);
        else
        {
            int q = sta[tl--];
            while(q!=to)
            {
                cir[q]=1;
                q=sta[tl--];
            }
            tl++;
            return 1;
        }
        if(cir[to])ret^=(now&1);
        else ret^=now;
    }
    return ret;
}
int main()
{
    while(scanf("%d",&T)>0)
    {
//    read(T);
        int ans=0;
        while(T--)
        {
            memset(hed,-1,sizeof(hed));
            memset(cir,0,sizeof(cir));
            memset(vis,0,sizeof(vis));
            memset(ban,0,sizeof(ban));
            cnt=-1;tl=0;
            read(n),read(m);
            for(int f,t,i=1;i<=m;i++)
            {
                read(f),read(t);
                ae(f,t),ae(t,f);
            }
            int now = dfs(1);
            ans^=now;
        }
        puts(ans?"Sally":"Harry");
    }
    return 0;
}

 

posted @ 2019-02-04 14:06  LiGuanlin  阅读(195)  评论(0编辑  收藏  举报