2019 icpc南昌邀请赛 G Winner

题目链接:https://nanti.jisuanke.com/t/40259

 

Ichuan really likes to play games, so he organized a game competition with NN participating players.

Follows are the rule of the game competition.

  1. There are three modes in the game, in each mode, players have different ability values, in addition, each player may have different ability value in different mode.

  2. There are a total of N-1 matches. In each match, two players who have not yet been eliminated will play against each other in one of the modes. The player who has high ability in this mode will win, and the other one will be eliminated.

  3. The only player who remains in the game after all N-1 matches will be the winner.

As the organizer of the game, ichuan can manipulate the result of the game. Namely, for each match, he can choose both players and match mode. Of course, he can only choose players who have not yet been eliminated.

Ichuan has some friends, some of them will ask him: "Does player XX will be the winner?" Answering this question will give you a lot of reward, so you need to write a program which can answer these questions.

Input

The first line contains integers N and Q(1N,Q105), the number of players and the number of requests.

The next three lines, each line contains N integers, the Xth integer Y(1Y106)represents the ability value of player X in this mode.,

The next qq lines, each line only has one integer X(1Xn), which means ichuan's friend wants to know if player X can be the winner.

Output

For each query, if player X has a chance to be the winner, output "YES", otherwise output "NO"

输出时每行末尾的多余空格,不影响答案正确性

样例输入复制
4 4 
1 2 3 4
1 2 4 3
2 1 3 4
1 
2 
3
4
样例输出复制
NO
NO 
YES 
YES   

题意:有n个选手,有3个比赛模式,每个模式下每个选手有一个实力值,实力值高者可以打败低者,裁判可以任意选择两个选手在任意模式下比赛,实力高者获胜,实力低着淘汰,q个询问,问裁判是否可以帮助玩家i在经历n-1场获胜

思路:三个模式,在每个模式下,按照实力排序,再将相邻实力高者与实力低者连边,缩点,入度为0的强连通分量的点都是可以获胜的点。

代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxm=1e6+10;
struct node{
    int u,v,w,nxt;
}e[maxm];
int h[maxn],low[maxn],dfn[maxn],vis[maxn];
int st[maxn],belong[maxn],du[maxn];
int n,q,cnt,tot,top,num,y;
struct nd{
    int x,id;
}a[maxn];
bool cmp(nd a1,nd a2)
{
    return a1.x<a2.x; 
}
void init()
{
    memset(h,-1,sizeof(h));
    memset(belong,0,sizeof(belong));
    memset(du,0,sizeof(du));
    memset(dfn,0,sizeof(dfn));
    memset(vis,0,sizeof(vis));
    cnt=tot=num=top=0;
}

void add(int u,int v)
{
    e[cnt].u=u,e[cnt].v=v;
    e[cnt].nxt=h[u];h[u]=cnt++;
}

void tarjan(int u)//缩点 
{
    dfn[u]=low[u]=++tot;
    vis[u]=1;
    st[++top]=u;
    for(int i=h[u];i!=-1;i=e[i].nxt)
    {
        int v=e[i].v;
        if(!dfn[v]) 
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);    
        }
        else if(vis[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        int t;
        num++;
        do{
            t=st[top--];
            vis[t]=0;
            belong[t]=num;
        }while(t!=u);
    }
}

int main()
{
    init();
    scanf("%d%d",&n,&q);
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[j].x);
            a[j].id=j;
        }
        sort(a+1,a+n+1,cmp);//排序 
        for(int j=1;j<n;j++)//连边 
            add(a[j+1].id,a[j].id);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            tarjan(i);
    for(int i=0;i<cnt;i++)//计算入度 
        if(belong[e[i].u]!=belong[e[i].v])
            du[belong[e[i].v]]++;
    for(int i=1;i<=q;i++)
    {
        scanf("%d",&y);
        if(du[belong[y]]==0)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/xiongtao/p/11248278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值