WerewolfTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1675 Accepted Submission(s): 473 Problem Description "The Werewolves" is a popular card game among young people.In the basic game, there are 2 different groups: the werewolves and the villagers.
Input The first line of the input gives the number of test cases T.Then T test cases follow.
Output For each test case,print the number of type-1 players and the number of type-2 players in one line, separated by white space.
Sample Input 1 2 2 werewolf 1 werewolf
Sample Output 0 0 Source 2018 Multi-University Training Contest 6 Recommend chendu | We have carefully selected several similar problems for you: 6373 6372 6371 6370 6369 |
【总结】
规律题咯。。没智商咯
【题意】
有n个人玩狼人杀。每个人指认一个其他人是狼或者平民,平民只说真话,而狼人不一定。
问最后有多少人必须为平民,多少人必为狼人?
【分析】
首先假设所有都是狼人,是成立的,所以必为平民的人就是0个咯。
一个人若必为狼人,则只有一种情况:1指认2是平民,2指认3是平民.....3指认1是狼,那1就必为狼,还有所有直接或间接指认1是平民的人也必为狼。
也就是说,我只关心指认平民的那个图,一个个的连通块,然后枚举指认别人是狼的那些人,比如u指认了x是狼,如果x直接或间接指认了u是平民,那所有直接或间接指认x和x都是狼。如图:红圈圈起来的都为狼。
那我们用并查集维护平民边构成连通块,遍历说别人是狼人的人,统计如上图这样的红圈中的点数即可。
【代码】
/****
***author: winter2121
****/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=2e5+5;
struct node{
int t,next;
}edge[MAX];
int head[MAX],cnt;
void init(int n)
{
cnt=0; memset(head,-1,sizeof(head[0])*(n+1));
}
void addedge(int u,int v)
{
edge[cnt]=node{v,head[u]};
head[u]=cnt++;
}
typedef pair<int,int>PII;
int fa[MAX];
int father(int x){return x==fa[x]?x:fa[x]=father(fa[x]);}
void join(int x,int y){x=father(x);y=father(y);fa[x]=y;}
void dfs(int u,int &ans)
{
ans++;
for(int i=head[u];~i;i=edge[i].next)
dfs(edge[i].t,ans);
}
int main()
{
int T,n,x,y;
char s[20];
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)fa[i]=i;
init(n);
queue<PII>q;
for(int i=1;i<=n;i++)
{
scanf("%d%s",&x,s);
if(s[0]=='w')q.push(PII(i,x));
else
{
addedge(x,i); //反向边
join(x,i);
}
}
int ans=0;
while(!q.empty())
{
PII u=q.front(); q.pop();
if(father(u.first)!=father(u.second))continue;
//u.second子树全为狼
dfs(u.second,ans);
}
printf("0 %d\n",ans);
}
return 0;
}