E
题:小X的战斗力(SFPA)
TimeLimit:1SecMemoryLimit:128MB
Submit:18Solved:6
[Submit][Status][WebBoard]
Description
小X才不是战五渣!为了证明这一点,小X进行了一些调查。
小X收集了班上一些同学之间决斗的胜负情况。决斗是两个人之间实力的比拼,实力用战斗力来衡量。小X猜想,战斗力高的人一定会在决斗中取得胜利。决斗一定会分出胜负,因此不存在战斗力相同的两人。
小X在调查分析自己的实力排名的同时,也顺便知道了其他一些同学的战斗力排名情况。现在你获取了这一批数据,请求出小X的调查结果。
因为小X并不怎么记得班上同学的名字,于是在数据中用数字来给同学们编号,从 1 到
N 。小X把自己标为 1 号。
Input
第一行为数据组数
T,T<=10
。
对于每组数据:
第一行为两个整数
N
和M(1<=N<=150,1<=M<=5000) 。
N
表示小X 班上同学的总人数,
M
表示小X 收集了
M
次决斗的信息。
接下来M 行,每行两个整数
A、B(1<=A,B<=N,A≠B)
,描述了一次决斗,决斗的结果是同学A胜出。
Output
对于每组数据:
如果小X的猜想没错,输出两行。第一行,如果可以确定小X的排名则输出一个整数
P
表示小X的排名,否则输出−1 ;第二行,输出一个整数
K
表示可以确定具体名次的班上同学的数量(包括小X自己)。
如果小X的猜想有误,输出一行一个字符串“Wrong” ,没有引号。
第一行为数据组数 T,T<=10 。
对于每组数据:
第一行为两个整数
N
和
接下来
对于每组数据:
如果小X的猜想没错,输出两行。第一行,如果可以确定小X的排名则输出一个整数
P
表示小X的排名,否则输出
如果小X的猜想有误,输出一行一个字符串
SampleInput
2
5 5
4 3
4 2
3 2
1 2
2 5
3 3
1 2
2 3
3 1
SampleOutput
-1
2
Wrong
HINT
对于第一组数据,可以确定名次的同学有
2
个,
题意
给你一定的排名关系,让你求出其中多少个顶点的排名已经固定,以及第一个人即小X的在排名中结果是多少?
解题思路
对于给定的
代码
时间复杂度: O(|V| 2 )
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e5 + 5;
int V,E;
bool succ;
struct Edge {
int u, v, next;
} G[MAXN];
struct o {
int x, y;
} O[MAXN];
int head[MAXN], e;
bool vis[MAXN];
int cnt[MAXN];
void add(int u,int v) {
G[e].u = u;
G[e].v = v;
G[e].next = head[u];
head[u] = e ++;
}
void SPFA(int s) {
queue<int>que;
for(int i = 1; i <= V; i ++) {
vis[i] = false;
}
vis[s] = true;
que.push(s);
while(!que.empty()) {
int temp = que.front();
que.pop();
for(int i = head[temp]; i != -1; i = G[i].next) {
int v = G[i].v;
if(!vis[v]) {
cnt[s] ++;
vis[v] = true;
que.push(v);
}
if(v == s) {
succ = false;
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
succ = true;
scanf("%d%d",&V,&E);
memset(head, -1, sizeof(head));
memset(cnt, 0, sizeof(cnt));
e = 0;
for(int i = 1; i <= E; i ++) {
scanf("%d%d",&O[i].x, &O[i].y);
add(O[i].x, O[i].y);
}
for(int i = 1; i <= V; i ++) {
SPFA(i);
}
int rkx = V - cnt[1];
memset(head, -1, sizeof(head));
e = 0;
for(int i = 1; i <= E; i ++) {
add(O[i].y, O[i].x);
}
for(int i = 1; i <= V; i ++) {
SPFA(i);
}
int ans = 0;
for(int i = 1; i <= V; i ++) {
if(cnt[i] == V - 1) {
ans ++;
} else {
if(i == 1) rkx = -1;
}
}
if(!succ) {
puts("Wrong");
} else {
printf("%d\n%d\n",rkx, ans);
}
}
return 0;
}