给你一颗树,然后上面有某些节点染了白色,其余的无色。
现在有两个人,两个人轮流染色。一个染白色,另一个人染黑色。
他们可以选择任意一个没有染色的点染色。如果最先有个人染的色有三个点连在一起,那么就胜出。
问谁必胜或平局。
要求 O ( n ) O(n) O(n)
真是一道神仙题。
一开始没有什么思路,然后手玩了一下样例也是没有思路。
然后想想不染色的情况。
然后就发现了三种情况(其中一种还是错的)
接下来染色的也没有什么好想法。
于是与lvle大爷疯狂讨论。
lvle大爷非常轻松地把这种情况给讨论出来了,其实就是链。
总结了几种小情况,然后就开码。
前后码了两次,然后再手玩很多小数据,还翻了翻英文题解发现不染色的情况还是讨论错了。最后终于是过了。
当然黑不可能胜出(壕无人性)
先考虑不染色的情况:
1、当某个点的度数大于等于4时,白必胜。
2、当某个点度数为3时,那么就看他连接的三个儿子。若其中有两个儿子有另外再多伸出一个儿子(度数大于等于2),那么白必胜。
若染色点大于等于3,则白必胜(可以归纳到上面的不染色情况)
若染色点的度数大于1,则白必胜(特判一下n=3的情况)
若两个染色点连在一起,则白必胜
接下来有三种情况:
情况是真滴多,调了好久。
然后就应该没啦
#include
#include
#include
#include
using namespace std;
const int maxn=500010;
int tot,las[maxn*2],tov[maxn*2],nex[maxn*2],rd[maxn],n,x[maxn],y[maxn];
char s[maxn];
void insert(int x,int y)
{
tot++;
tov[tot]=y;
nex[tot]=las[x];
las[x]=tot;
}
int main()
{
int T,n;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
tot=0;
for (int i=1;i<=2*n;i++)
{
las[i]=0;
}
for (int i=1;i<=n;i++)
{
rd[i]=0;
}
for (int i=1;i<n;i++)
{
scanf("%d%d",&x[i],&y[i]);
insert(x[i],y[i]);
insert(y[i],x[i]);
rd[x[i]]++;
rd[y[i]]++;
}
scanf("%s",s+1);
bool bz=true;
bool pd=true;
int gs=0;
for (int i=1;i<=n;i++)
{
if (s[i]=='W')
{
pd=false;
gs++;
}
}
// if (pd)
// {
int cnt=0;
for (int i=1;i<=n;i++)
{
if (rd[i]>=4)
{
bz=false;
break;
}
int k=0;
if (rd[i]==3)
{
cnt++;
for (int j=las[i];j;j=nex[j])
{
if (rd[tov[j]]>=2) k++;
}
}
if (k>=2)
{
bz=false;
break;
}
k=0;
if (rd[i]==2)
{
for (int j=las[i];j;j=nex[j])
{
if (rd[tov[j]]==3) k++;
}
}
if (k>=2)
{
bz=false;
break;
}
}
if (cnt==2)
{
if ((n-6)%2==1)
{
printf("White\n");
continue;
}
}
if (!bz)
{
printf("White\n");
continue;
}
if (n==3)
{
if (gs>=2)
{
printf("White\n");
continue;
}
else
{
printf("Draw\n");
continue;
}
}
// }
if (!pd)
{
if (gs>2)
{
printf("White\n");
continue;
}
bool pp=false;
for (int i=1;i<=n;i++)
{
if (s[i]=='W' && rd[i]>=2)
{
bz=false;
break;
}
if (s[i]=='W')
{
bool op=true;
for (int j=las[i];j;j=nex[j])
{
if (s[tov[j]]=='W' || rd[tov[j]]>2)
{
op=false;
break;
}
}
if (!op)
{
bz=false;
break;
}
}
if (rd[i]==3)
{
pp=true;
}
}
if (!bz)
{
printf("White\n");
continue;
}
if (gs==1)
{
if (n%2==0 && pp)
{
printf("White\n");
continue;
}
}
if (gs==2)
{
if (n%2==1)
{
printf("White\n");
continue;
}
}
}
printf("Draw\n");
}
}