hdu6370 辣鸡xiaolver8.9多校赛第二天尝试写一个有点含量的t

首先题意:有n个玩家每个玩家说一句话.话是  数字n+猜测身份.输出最少可能的人和狼。人必须说真话,狼可说真可说假

.首先如果都是狼,显然有这种可能,所以人最少就是0了。

第二我们能从一只狼推出另一只.说铁狼不是狼的一定是狼(人不能说假话)如何找铁狼呢?

先从简单的开始.如果没有头绪可以分析一下题.狼说的话可真可假.人必须说真话!那狼的话便没有用.需要从人的话开始分析.那如果只有两玩家,当A说B是人,B说A是狼.如果A是人.那此时B说A是狼.显然矛盾.这样A的狼身份就坐实.这种假设需要扩展.可能有许多玩家,这种判断过程可以扩展的是A说B是人的环节.只要A信任的人信任最后到了B,而B却认为A是狼.A此时就是铁狼.

然后加上我们一开始意识到的说铁狼不是狼的一定是狼.算出所有狼的个数.

想完了写的时候却很头疼.

#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <math.h>
#include <iomanip>
#include <queue>
#include <map>
#define sd(qwe) scanf("%d",&qwe)
#define se(cvb) scanf("%lf",&cvb)
#define ss(asd) scanf("%s",asd)
#define sc(xcv) scanf("%c",&xcv)
#define xh(ert,rty,tyu) for(int ert=rty;ert<=tyu;ert++)
#define fxh(u,i,o) for(int u=i;u>=o;u--)
#define maxn 200005
using namespace std;
int num,ans,head[maxn],f[maxn],vis[maxn];
struct Edge
{
    int s,p,next,w;
}edge[maxn];
int findf(int s)
{
    if(s==f[s])return s;
    else return f[s]=findf(f[s]);
}
void addEdge(int s,int p,int w)
{
    edge[num].s=s;edge[num].p=p;edge[num].w=w;edge[num].next=head[p];head[p]=num++;
}
void Union(int s,int p)
{
    if(findf(p)==findf(s))return;
    else f[findf(p)]=findf(s);
}
int main()
{int k;sd(k);
    while(k--)
    {
        int p;sd(p);
        ans=0;num=0;
        memset(head,-1,sizeof(head));
        xh(i,1,p)f[i]=i;
        xh(i,1,p){
        int d;sd(d);
        char str[10];ss(str);
        if(str[0]=='w')addEdge(i,d,1);else{addEdge(i,d,0);Union(i,d);}
        }
        memset(vis,0,sizeof(vis));
        queue<int>que;
        xh(i,0,num-1)
        {int s=edge[i].s,w=edge[i].w,p=edge[i].p;
            if(findf(s)==findf(p)&&w==1&&!vis[p])
            {
                ans++;
                que.push(p);vis[p]=1;
            }
        }
        while(!que.empty())
        {
            int fuck=que.front();que.pop();
            for(int i=head[fuck];i!=-1;i=edge[i].next)
            {
                int s=edge[i].s,w=edge[i].w;
                if(w)continue;
                if(vis[s])continue;
                ans++;
                que.push(s);
            }
        }
        printf("0 %d\n",ans);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35557621/article/details/81538862