http://acm.split.hdu.edu.cn/showproblem.php?pid=5963
题意:中文题
博弈,找了下规律,瞎几把写了个N*M的dfs,T了,没想到能过小数据。。。。
看了下题解,大多是找规律,其实仔细想想,好像很对
修改暴力修改就好了
查询:对每个查询只看这个点直接相连的边里有几个为1的,奇数个则Girl Win ,偶数个Boy Win
仔细分析一下,单纯看每条链,设和根节点连着的这条边为V
1. V=1,先手必赢,先手就改V,因为无论下面有多少个1,每次翻下面的都会把V从0改回1,这样我可以继续改V
2.V=0,先手必输,下面没有等于1的边,先手肯定就是输的,下面无论有几条等于1的边,先手每次改掉之后,V都会从0改为1,这样后手每次都改V,这样后手肯定会赢
如果有奇数条先手必赢的链,那么一定是可以让后手这个人去 先手 改剩下的先手必输的链
如果有偶数条先手必赢的链,那么只能是让自己去 先手 改剩下的先手必输的链
#include<bits/stdc++.h>
using namespace std;
struct node
{
int ne,v;
bool operator < (const node u)const
{
return ne<u.ne;
}
};
int ans;
vector<node>w[50000];
int main()
{
int n,m,i,j,T,u,v,x;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
node te;
for(i=0;i<=n;i++)
w[i].clear();
for(i=1;i<n;i++)
{
scanf("%d %d %d",&u,&v,&x);
te.ne=u;te.v=x;
w[v].push_back(te);
te.ne=v;
w[u].push_back(te);
}
for(i=1;i<=n;i++)
sort(w[i].begin(),w[i].end());
while(m--)
{
int cc;
scanf("%d",&cc);
if(cc)
{
scanf("%d %d %d",&u,&v,&x);
te.ne=v,te.v=x;
*(lower_bound(w[u].begin(),w[u].end(),te))=te;//修改似乎直接暴力也可以。。。。
te.ne=u;
*(lower_bound(w[v].begin(),w[v].end(),te))=te;
}
else
{
int root;
scanf("%d",&root);
ans=0;
for(i=0;i<w[root].size();i++)
ans^=w[root][i].v;
if(ans==0)
printf("Boys win!\n");
else
printf("Girls win!\n");
}
}
}
return 0;
}