HDU - 6370 Werewolf 2018 Multi-University Training Contest 6 (DFS找环)

求确定身份的人的个数。

只能确定狼的身份,因为只能找到谁说了谎。但一个人是否是民,无法确定。

将人视作点,指认关系视作边,有狼边和民边两种边。

确定狼的方法只有两种:

  1. 在一个仅由一条狼边组成的环中,狼边指向的那个点必定是狼。

  2. 环外指认铁狼为民的也必定是狼。

所以用原图找环求情况1中的铁狼,反向建图找情况2中的狼。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn =1e5+5;
const int INF =0x3f3f3f3f;
struct Edge{
    int v;bool w;
};
Edge G[maxn];
vector<Edge> rG[maxn];
int pre[maxn],dfn;
bool isw[maxn];
queue<int> Q;
int res;

void init(int N){
    res=0;
    memset(pre,0,sizeof(pre));
    memset(isw,0,sizeof(isw));
    for(int i=1;i<=N;++i) rG[i].clear();
}

void AddEdge(int u,int v,bool w){
    G[u] = (Edge){v,w};
    rG[v].push_back((Edge){u,w});
}

void BFS()
{
    while(!Q.empty()){
        int u = Q.front();Q.pop();
        for(int i=0;i<rG[u].size();++i){
            Edge &e =rG[u][i];
            if(!e.w && !isw[e.v]){
                Q.push(e.v);
                isw[e.v] = true;
            }
        }
    }
}

void Tarjan(int u){
    int v;bool w;
    pre[u]=2;
    v= G[u].v;
    w = G[u].w;
    if(!pre[v])
        Tarjan(v);
    else if(pre[v]==2){                   //找到环
        int cnt=0, tar,t;
        for(t=v;;t= G[t].v){
            Edge &e = G[t];
            if(e.w){
                cnt++;
                tar = G[t].v;
            }
            if(e.v==v) break;
        }
        if(cnt==1){                    //只有一个狼边才行
            isw[tar] = true;
            Q.push(tar);
        }
    }
    pre[u]=1;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("1009.out","w",stdout);
    #endif
    int T,N,u,v,tmp;
    char op[20];
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        init(N);
        for(int u=1;u<=N;++u){
            scanf("%d %s",&v,op);
            if(op[0]==‘w‘) AddEdge(u,v,1);
            else AddEdge(u,v,0);
        }

        for(int i =1;i<=N;++i){
            if(!pre[i])
                Tarjan(i);
        }
        BFS();
        for(int i=1;i<=N;++i)
            if(isw[i])  res++;
        printf("%d %d\n",0,res);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xiuwenli/p/9445527.html

时间: 2024-10-12 15:11:44

HDU - 6370 Werewolf 2018 Multi-University Training Contest 6 (DFS找环)的相关文章

HDU 6370 Werewolf 【并查集】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6370 Werewolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2680    Accepted Submission(s): 806 Problem Description "The Werewolves" is a p

2018 Nowcoder Multi-University Training Contest 2

Practice Link A. run 题意: 白云每次可以移动\(1\)米或者\(k\)米,询问移动的米数在\([L, R]\)范围内的方案数有多少. 思路: \(dp[i][2]\)表示到第\(i\)米,是通过\(1\)米的方式过来的还是\(k\)米的方式过来的,递推即可. 代码: #include <bits/stdc++.h> using namespace std; #define N 100010 const int p = 1e9 + 7; int f[N][2], g[N];

2018 Nowcoder Multi-University Training Contest 1

Practice Link J. Different Integers 题意: 给出\(n\)个数,每次询问\((l_i, r_i)\),表示\(a_1, \cdots, a_i, a_j, \cdots, a_n\)中有多少个不同的数. 思路: 先分别离线求出\(a_1, \cdots a_i\)以及\(a_j, \cdots, a_n\)中有多少个不同的数. 再考虑有多少个数既在\([1, i]\)中也在\([j, n]\)中,再离线做一次. 考虑一个数第一次出现的时候,那么这个数下一次出现

2018 Nowcoder Multi-University Training Contest 5

Practice Link A. gpa 题意: 有\(n\)门课程,每门课程的学分为\(s_i\),绩点为\(c_i\),要求最多删除\(k\)门课程,使得gpa最高. gpa计算方式如下: \[ \begin{eqnarray*} gpa = \frac{\sum s_ic_i}{\sum s_i} \end{eqnarray*} \] 思路: 首先删去的课程越多,gpa肯定不会变得更差. 所以我们肯定是删去\(k\)门课程. 考虑二分答案,check的时候要满足: \[ \begin{eq

HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 5943    Accepted Submission(s): 2004 Problem Description Before

HDU 6396 Swordsman --------2018 Multi-University Training Contest 7 (模拟+读入挂)

原题地址: 打怪升级 一开始有N个怪物:主角有K个能力:只有K个能力都击败怪物才能斩杀怪物并获得K个能力的增值:问最多能杀几个怪物: 做法: 用优先队列把怪物能力装进去:能力小放前面: 最重要的是数据量要用读入挂才能过:(读入挂太神奇了!!) Swordsman Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2049    Acce

2018 Multi-University Training Contest 1 Distinct Values 【贪心 + set】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6301 Distinct Values Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5312    Accepted Submission(s): 1823 Problem Description Chiaki has an array of

2018 Multi-University Training Contest 4 Problem L. Graph Theory Homework 【YY】

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6343 Problem L. Graph Theory Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1536    Accepted Submission(s): 830 Problem Description Ther

2018 Multi-University Training Contest 4 Problem K. Expression in Memories 【模拟】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6342 Problem K. Expression in Memories Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2150    Accepted Submission(s): 772Special Judge Problem De