Episode N-th: The Jedi Tournament
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Decided several Jedi Knights to organize a tournament once. To know, accumulates who the largest amount of Force. Brought each Jedi his lightsaber with him to the tournament. Are different the lightsaber, and Jedi different are. Three parameters there are: length of the saber, Force of the Jedi and how good the Light side of the Force the Jedi can use. If in at least two parameters one Jedi than the other one stronger is, wins he. Is not possible a draw, because no Jedi any equal parameter may have. If looses a Jedi, must leave the tournament he.
To determine, which Jedi the tournament can win, your program is. Can win the tournament a Jedi, if at least one schedule for the tournament possible is, when the last one remains he on the tournament, not looses any match. For example, if Anakin stronger than Luke by some two parameters is, and Luke stronger than Yoda by some two parameters is, and Yoda stronger than Anakin, exists in this case a schedule for every Jedi to win the tournament.
Input
In the first line there is a positive integer N ≤ 200, the total number of Jedi. After that follow N lines, each line containing the name of the Jedi and three parameters (length of the lightsaber, Force, Light side in this order) separated with a space. The parameters are different integers, not greater than 100000 by the absolute value. All names are sequences of not more than 30 small and capital letters.
Output
Your program is to output the names of those Jedi, which have a possibility to win the tournament. Each name of the possible winner should be written in a separate line. The order of the names in the output should correspond to the order of their appearance in the input data.
Sample
input | output |
---|---|
5 Solo 0 0 0 Anakin 20 18 30 Luke 40 12 25 Kenobi 15 3 2 Yoda 35 9 125 |
Anakin Luke Yoda |
Problem Author: Leonid Volkov
【分析】绝地大师比武,每个绝地大师有三个参数,设为a,b,c;对于两个绝地大师甲和乙,如果甲有两个参数大于乙,则甲能打过乙,如果对于三个人甲乙丙,若甲能打过乙,乙能打过丙,丙能打过甲,且无其他人打得过他们,则他们三都第一。现在给你一些绝地大师的姓名及参数,让你找第一。
做法就是强连通分量缩点,每个强连通分量里的点都是同一排名不分上下的,现在就是找缩点后入度为零的点。
#include <stdio.h> #include <string.h> #include <cmath> #include <iostream> #include <stack> #include <queue> #include <algorithm> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back typedef long long ll; using namespace std; const int N = 505; const int M = 124750+10; int n,m,k,s,t,tot,cut=0,tim=0,top=0; int head[N],vis[N],dis[N]; int dfn[N],low[N],stack1[N],num[N],in[N],out[N]; struct node{ string s;int a,b,c; }no[N]; struct man{ int to,next; }edg[M]; void add(int u,int v){ edg[tot].to=v;edg[tot].next=head[u];head[u]=tot++; } int charge(int x,int y){ if(x>y)return 1;else return 0; } void Tarjan(int u){ int v; low[u] = dfn[u] = ++tim; stack1[top++] = u; vis[u] = 1; for(int e = head[u]; e != -1; e = edg[e].next){ v = edg[e].to; if(!dfn[v]){ Tarjan(v); low[u] = min(low[u], low[v]); } else if(vis[v]){ low[u] = min(low[u], dfn[v]); } } if(low[u] == dfn[u]){ cut++; do { v = stack1[--top]; num[v] = cut; vis[v] = 0; }while(u != v); } } int main() { int u,v,val;tot=0;met(dfn,0);met(vis,0);met(head,-1); scanf("%d",&n); string str; for(int i=1;i<=n;i++){ cin>>no[i].s>>no[i].a>>no[i].b>>no[i].c; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(charge(no[i].a,no[j].a)+charge(no[i].b,no[j].b)+charge(no[i].c,no[j].c)>=2){ add(i,j); } } } for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i); for(int i=1;i<=n;i++){ for(int j=head[i];j!=-1;j=edg[j].next){ int v=edg[j].to; if(num[i]!=num[v])out[num[i]]++,in[num[v]]++; } } int father; for(int i=1;i<=cut;i++){ if(!in[i]){father=i;break;} } for(int i=1;i<=n;i++){ if(num[i]==father){ cout<<no[i].s<<endl; } } return 0; }