1218. Episode N-th: The Jedi Tournament

http://acm.timus.ru/problem.aspx?space=1&num=1218

缩点后形成树  树的根节点 就是有可能获胜的点

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<vector>

#include<map>

#include<cmath>

#include<queue>

#include<stack>

#include<algorithm>



#define LL long long

//#pragma comment(linker, "/STACK:1024000000,1024000000")



using namespace std;

const int INF=0x3f3f3f3f;

const int N=205;

struct node

{

    string name;

    int a[3];

}mem[N];

bool beat[N][N];

int low[N],dfn[N],deep;

bool in[N],visited[N],maybewin[N];

int f[N];

stack<int>St;

int n;

void Tarjan(int x)

{

    low[x]=dfn[x]=deep++;

    visited[x]=true;

    St.push(x);

    in[x]=true;

    for(int l=1;l<=n;++l)

    {

        if(beat[x][l]==false)

        continue;

        if(!visited[l])

        {

            Tarjan(l);

            low[x]=min(low[x],low[l]);

        }else if(in[l])

        {

            low[x]=min(low[x],dfn[l]);

        }

    }

    if(low[x]==dfn[x])

    {

        while(St.top()!=x)

        {

            f[St.top()]=x;

            in[St.top()]=false;

            St.pop();

        }

        f[St.top()]=x;

        in[St.top()]=false;

        St.pop();

    }

}

bool Kill(int i,int j)

{

    int k=0;

    for(int l=0;l<3;++l)

    if(mem[i].a[l]>mem[j].a[l])

    ++k;

    if(k>=2)

    return true;

    return false;

}

int main()

{

    //freopen("data.txt","r",stdin);

    while(cin>>n)

    {

        for(int i=1;i<=n;++i)

        {

            cin>>mem[i].name;

            for(int j=0;j<3;++j)

            cin>>mem[i].a[j];

        }

        memset(beat,false,sizeof(beat));

        for(int i=1;i<=n;++i)

        for(int j=1;j<=n;++j)

        if(Kill(i,j))

        beat[i][j]=true;

        memset(visited,false,sizeof(visited));

        for(int i=1;i<=n;++i)

        if(!visited[i])

        Tarjan(i);

        memset(maybewin,true,sizeof(maybewin));

        for(int i=1;i<=n;++i)

        {

            for(int j=1;j<=n;++j)

            if(beat[i][j]&&f[i]!=f[j])

            maybewin[f[j]]=false;

        }

        for(int i=1;i<=n;++i)

        {

            if(maybewin[f[i]])

            cout<<mem[i].name<<endl;

        }

    }

    return 0;

}

 

你可能感兴趣的:(name)