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

本文介绍了一种通过构建图论模型来确定狼人杀游戏中狼人身份的算法。通过寻找特定条件下的环和反向图中的指认关系,可以精确找出说谎者即狼人的身份。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

求确定身份的人的个数。

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

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

确定狼的方法只有两种:

  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

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值