您的位置:首页 > 其它

PKU3710

2011-06-15 14:37 387 查看
/*
稍有难度的题目。sg游戏
树删边游戏。不过在树的基础上加入了环,这个环是一个特殊的环,每个环和树只有一个公共节点,没有公共边。而且存在重边。所以对于无向图的保存需要注意
这里除了记录下每个节点的连接边以外,还要记录每两个节点之间边的个数。
然后分析环的特性:没一个环最终都可以化简,奇数环可以化简为一条边,偶数环可以删去,详细可参见论文。
*/

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

int N;
int M,K;
vector<int> G[110];
int sg[110];
int ans[110];
bool used[110];
int Ismany[110][110];

void rang(int ct,int be,int f,int cnt,int &ans,int &last)
{
used[be] = 1;

for(int i=G[be].size()-1;i>=0;i--)
{
if(Ismany[be][G[be][i]]==1)
{
if( G[be][i]==ct )
{
last = be;
ans = cnt+1;break;
}
if( !used[G[be][i]] )
{
Ismany[be][G[be][i]]--;
Ismany[G[be][i]][be]--;
rang(ct,G[be][i],f,cnt+1,ans,last);
Ismany[be][G[be][i]]++;
Ismany[G[be][i]][be]++;
}
}
}

if(f) used[be] = 0;
}

int dfs(int x)
{
int& cur = sg[x];
if(cur!=-1) return cur;

cur = 0;
used[x] = 1;
int cnt,ans,last;
for(int i=G[x].size()-1;i>=0;i--)
{
if( !used[G[x][i]] )
{
if( Ismany[x][G[x][i]]>1 )
{
used[G[x][i]] = 1;
continue;
}

ans = -1;
cnt = 1;
last = -1;

Ismany[x][G[x][i]]--;
Ismany[G[x][i]][x]--;
rang(x,G[x][i],1,cnt,ans,last);
Ismany[x][G[x][i]]++;
Ismany[G[x][i]][x]++;

if( ans!=-1 )
{
if(ans&1) cur^=1;
else cur^=0;
}
if(ans!=-1)
{
used[G[x][i]] = 1;
used[last] = 1;
}
else
{
cur ^= (dfs(G[x][i])+1);
}
}
}

return cur;
}

int main()
{
int s,t;
while(scanf("%d",&N)==1)
{
for(int i=0;i<N;i++)
{
scanf("%d %d",&M,&K);
for(int j=1;j<=M;j++) G[j].clear();
memset(Ismany,0,sizeof(Ismany));
for(int j=0;j<K;j++)
{
scanf("%d %d",&s,&t);
Ismany[s][t]++;
Ismany[t][s]++;
G[s].push_back(t);
G[t].push_back(s);
}

//
memset(sg,-1,sizeof(sg));
memset(used,0,sizeof(used));
ans[i] = dfs(1);
//printf("sg: %d\n",ans[i]);
}

int win = 0;
for(int i=0;i<N;i++)
win ^= ans[i];
if(win) printf("Sally\n");
else printf("Harry\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: