I - 排名表

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit Status

暑假前集训已经过了一半了,我们将会把当前排名公布出来。但是此刻秋实大哥却心急火燎,因为他不慎把排名删除了。

一共有n个人参加排名,每个人都有一个名次,没有哪两个人的名次是相同的。现在秋实大哥掌握的一些情报,比如Ai的名次要先于Bi。(编号从1开始)

你能帮秋实大哥恢复出排名表吗?

Input

第一行一个数字 T (T≤10),表示测试数据组数

每组测试数据,第一行两个数 n(1≤n≤200)和 m(0≤m≤40000),接下来m行,每行两个数a和b(1≤a,b≤N),表示a的名次要先于b

Output

对于每组测试数据,输出一行,从1号到n号每个人的名次。

如果有多个解,让编号为1的人的名次尽量小,然后让编号为2的人的名次尽量小,然后让编号为3的人的名次尽量小......

如果没有解,输出−1

Sample input and output

Sample Input Sample Output
5
4 0
4 1
1 1
4 2
1 2
2 1
4 1
2 1
4 1
3 2
1 2 3 4
-1
-1
2 1 3 4
1 3 2 4

Hint

注意可能会有重边

解题思路:

首先,本题正向拓扑排序是不行的,即如果这样建边:

U 的名次先于 V , 即 V 向 U连边

因为题意比较绕,下文都这样叙述:

排名号越高,其名次越低,第一名的排名号是 1 ,它的名次是最高的.

我们按照 v 向 u建边,意思是v的排名号高于u.

无法保证

让编号为1的人的名次尽量小,然后让编号为2的人的名次尽量小,然后让编号为3的人的名次尽量小.

è 让编号为 1 的人的排名号尽量大,然后让编号为 2 的人的排名号尽量大….

我们拓扑排序的顺序是这样的:

每次寻找入度为 0 的点,将排名号赋给这个点,删边,重复.

如果有多个点入度都是 0 呢?我们不假思索的这样想:

 我们为了保证题目条件,会使得我们会尽量保证这个点的编号尽量小(这样我们看起来符合了题目条件:编号小的人排名号尽量高),但是我们忽略了,题目要求是先尽力保证编号1的人,之后才是编号2的人….

所以,正向建边是错误的

注意,上面的证明非常不严格(Even it's a mistake),如果小伙伴谁有更好的证明,可在下面回复

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#define pb push_back
using namespace std;
const int maxn = + ;
int n,m,c[maxn],indig[maxn];
vector<int>E[maxn];
bool existedge[maxn][maxn];
int out[maxn]; bool dfs(int cur)
{
if (c[cur] == )
return true;
c[cur] = -;
for(int i = ; i < E[cur].size() ; ++ i)
{
int nextnode = E[cur][i];
if (c[nextnode] == -)
return false;
if (!c[nextnode] && !dfs(nextnode)) //exist 环
return false;
}
c[cur] = ;
return true;
} typedef struct point
{
int id,indig;
friend bool operator < (const point & x,const point & y)
{
return x.indig < y.indig;
}
point(int id,int indig)
{
this->id = id , this->indig = indig;
}
}; vector<point>v;
bool used[maxn]; void ansset()
{
memset(used,false,sizeof(used));
for(int i = ; i <= n ; ++ i)
v.pb(point(i,indig[i]));
sort(v.begin(),v.end());
int rank = ;
for(int i = ; i <= n ; ++ i)
{
int choose = v[].id;
int pos = ;
while( pos < v.size() && !v[pos].indig)
choose = max(choose,v[pos++].id);
out[choose] = n - rank++;
used[choose] = true;
for(int i = ; i < E[choose].size() ; ++ i)
indig[E[choose][i]]--;
v.clear();
for(int i = ; i <= n ; ++ i)
if(!used[i])
v.pb(point(i,indig[i]));
sort(v.begin(),v.end());
}
} int main(int argc,char *argv[])
{
int Case;
scanf("%d",&Case);
while(Case--)
{
scanf("%d%d",&n,&m);
memset(c,,sizeof(c));
memset(existedge,false,sizeof(existedge));
memset(indig,,sizeof(indig));
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
if (existedge[v][u])
continue;
E[v].pb(u);
existedge[v][u] = true;
indig[u] ++;
}
int ans = ;
for(int i = ; i <= n ; ++ i)
if (!dfs(i))
{
ans = ;
break;
}
if (!ans)
printf("-1\n");
else
{
v.clear();
ansset();
for(int i = ; i <= n ; ++ i)
i == ? printf("%d",out[i]) : printf(" %d",out[i]);
printf("\n");
}
for(int i = ; i <= n ; ++ i)
E[i].clear();
}
return ;
}

UESTC_排名表 2015 UESTC Training for Graph Theory<Problem I>的更多相关文章

  1. UESTC_传输数据 2015 UESTC Training for Graph Theory<Problem F>

    F - 传输数据 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  2. UESTC_方老师和农场 2015 UESTC Training for Graph Theory<Problem L>

    L - 方老师和农场 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  3. UESTC_王之盛宴 2015 UESTC Training for Graph Theory<Problem K>

    K - 王之盛宴 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  4. UESTC_小panpan学图论 2015 UESTC Training for Graph Theory<Problem J>

    J - 小panpan学图论 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) S ...

  5. UESTC_韩爷的情书 2015 UESTC Training for Graph Theory<Problem H>

    H - 韩爷的情书 Time Limit: 6000/2000MS (Java/Others)     Memory Limit: 262144/262144KB (Java/Others) Subm ...

  6. UESTC_树上的距离 2015 UESTC Training for Graph Theory<Problem E>

    E - 树上的距离 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 262143/262143KB (Java/Others) Subm ...

  7. UESTC_邱老师的脑残粉 2015 UESTC Training for Graph Theory<Problem D>

    D - 邱老师的脑残粉 Time Limit: 12000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

  8. UESTC_秋实大哥与时空漫游 2015 UESTC Training for Graph Theory<Problem C>

    C - 秋实大哥与时空漫游 Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Su ...

  9. UESTC_秋实大哥带我飞 2015 UESTC Training for Graph Theory<Problem B>

    B - 秋实大哥带我飞 Time Limit: 300/100MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit ...

随机推荐

  1. Windows 8.1下使用IE 64位

    Internet Options -> Advanced -> Settings Security组 对Enable 64-bit processes for Enhanced Prote ...

  2. maven compile时出现“非法字符: \65279”的解决

    我碰到的这个问题是因为Java文件编码为UTF-8 BOM格式导致:解决这个可以使用UltraEdit. 用UltraEdit打开出问题的Java文件,将文件另存为,在保存对话框的编码中选择UTF-8 ...

  3. Saruman's Army (POJ 3069)

    直线上有N个点.点i的位置是Xi.从这N个点中选择若干个,给它们加上标记.对每一个点,其距离为R以内的区域里必须又带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点).在 ...

  4. sicily 1155 Can I Post the letter

    题意:判断有向图两点之间是否可通达! 解法:深搜或广搜(注意避免旧路重行) DFS: #include<iostream> #include<vector> #include& ...

  5. c语言学习之结构篇代码演示样例-输入n个同学的姓名,数学英语成绩,依照平均分从低到高排序并输出

    #include<stdio.h> void main(){ const int count = 5;//定义数量 struct student{ char name[80]; float ...

  6. Fragment的简单使用

    最近一直有点忙,刚刚看到一个朋友的留言提到Fragment中加载ListView的问题,这里写了一个非常简单的测试,至于对Fragment的增.删.改实现动态布局构建灵活的UI,以后有时间在讨论: M ...

  7. Counting Squares_hdu_1264(矩阵).java

    Counting Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. DB2查询当前时间与指定时间的时间差(相隔的秒数)

    DB2查询当前时间与指定时间的时间差(相隔的秒数). 例子:“拍品表 auct_item”中有个“结束时间 end_date”的字段,求结束时间与当前时间的间隔秒数. select  (DAYS(a. ...

  9. HDU 4588 Count The Carries 计算二进制进位总数

    点击打开链接 Count The Carries Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...

  10. vsim生成VCD波形文件(verilog)

    Vsim(ModelSim)生成VCD波形文件(verilog) 两种方法 方法一: 调用ModelSim自己的命令生成,仿真脚本中加入如下一句即可 vcd file mytb.vcd 方法二: 调用 ...