HDU 6370 dfs+并查集

Werewolf

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1381    Accepted Submission(s): 386


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.

Each player will debate a player they think is a werewolf or not. 

Their words are like "Player x is a werewolf." or "Player x is a villager.".

What we know is :

1. Villager won't lie.

2. Werewolf may lie. 

Of cause we only consider those situations which obey the two rules above. 

It is guaranteed that input data exist at least one situation which obey the two rules above.

Now we can judge every player into 3 types :

1. A player which can only be villager among all situations, 

2. A player which can only be werewolf among all situations.

3. A player which can be villager among some situations, while can be werewolf in others situations.

You just need to print out the number of type-1 players and the number of type-2 players. 

No player will talk about himself.
 
Input
The first line of the input gives the number of test cases T.Then T test cases follow.

The first line of each test case contains an integer N,indicating the number of players.

Then follows N lines,i-th line contains an integer x and a string S,indicating the i-th players tell you,"Player x is a S."

limits:

1T10

1N100,000

1xN

S {"villager"."werewolf"}
 
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

 解析    题解说的还是比较明白的,村名的数量一定是0  存在铁狼只有一种情况   (狼人边指向树中某个节点)

思路就是 找所有   除了根节点指出的边是狼人边   其他节点指出的边都是好人边组成的基环树   狼人边所指的那个子树大小就是铁狼的数量

比如 2,3,1,4,5,6 是满足条件的 基环树  铁狼的个数就是  sz[4]=4 (方框指向的是另一个联通块 所以不存在铁狼)

只有n条边  并查集  dfs 标记什么的 搞一搞 就过了

AC代码   写的太丑了

 1 #include <bits/stdc++.h>
 2 #define mp make_pair
 3 #define pb push_back
 4 #define fi first
 5 #define se second
 6 #define all(a) (a).begin(), (a).end()
 7 #define fillchar(a, x) memset(a, x, sizeof(a))
 8 #define huan printf("\n");
 9 #define debug(a,b) cout<<a<<" "<<b<<" "<<endl;
10 using namespace std;
11 typedef long long ll;
12 const ll maxn=1e5+20,inf=1e18;
13 const ll mod=1e9+7;
14 vector<pair<int,int> > g[maxn],gg[maxn];
15 int vis[maxn],sz[maxn];
16 int par[maxn];
17 int _find(int x)
18 {
19     return x==par[x]?x:par[x]=_find(par[x]);
20 }
21 void unio(int a,int b)
22 {
23     int ra=_find(a);
24     int rb=_find(b);
25     if(ra!=rb)
26         par[rb]=ra;
27 }
28 void dfs2(int x)//把 子树的大小求出来 并且把树归到一个集合 
29 {
30     sz[x]=1;vis[x]=1;
31     for(int i=0;i<gg[x].size();i++)
32     {
33         pair<int,int> it=gg[x][i];
34         if(vis[it.fi]==0)
35         {
36             dfs2(it.fi);
37         }
38         unio(x,it.fi);
39         sz[x]+=sz[it.fi];
40     }
41 }
42 char s[20];
43 int main()
44 {
45     int t,n;
46     scanf("%d",&t);
47     while(t--)
48     {
49         scanf("%d",&n);
50         int temp1,temp2;
51         for(int i=1;i<=n;i++)
52         {
53             g[i].clear(),gg[i].clear();
54             par[i]=i;
55             vis[i]=sz[i]=0;
56         }
57         for(int i=1;i<=n;i++)
58         {
59             scanf("%d%s",&temp1,s);
60             if(s[0]=='w')temp2=0;
61             else temp2=1;
62             g[i].pb(mp(temp1,temp2));
63             if(temp2==1)
64                 gg[temp1].pb(mp(i,temp2));
65         }
66         int ans=0;
67         for(int i=1;i<=n;i++)
68         {
69             if(vis[i]==0&&gg[i].size()>0)//没被访问过 且有子节点
70                 dfs2(i);
71         }
72         for(int i=1;i<=n;i++)
73         {
74             if(_find(g[i][0].fi)==_find(i)&&g[i][0].se==0)//指出的是狼边  且狼边指向自己所在的树
75                 ans+=sz[g[i][0].fi];
76         }
77         printf("0 %d\n",ans);
78     }
79 }
80 
81 //4 v 1
82 //1 v 2
83 //1 v 3
84 //5 v 4
85 //6 v 5
86 //4 w 6
87 //4 w 7
88 //6 v 8
89 //10
90 //8
91 //4 v
92 //1 v
93 //1 v
94 //5 v
95 //6 v
96 //4 w
97 //4 w
98 //6 v

猜你喜欢

转载自www.cnblogs.com/stranger-/p/9450821.html