• cdoj 1150 排名表 拓扑排序


    题目链接:

    题目

    排名表
    Time Limit: 1000MS
    Memory Limit: 65535KB
    64bit IO Format: %lld & %llu

    问题描述

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

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

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

    输入

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

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

    输出

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

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

    如果没有解,输出

    样例

    input
    5
    4 0
    4 1
    1 1
    4 2
    1 2
    2 1
    4 1
    2 1
    4 1
    3 2

    output
    1 2 3 4
    -1
    -1
    2 1 3 4
    1 3 2 4

    Hint
    注意可能会有重边

    题解

    首先,题目并不是让你求最小的字典序!
    其次,我们可以这样理解:要让编号i的排名靠前,只要把能够排在它后面的并且排名比它大的都排在后面就可以了,所以,我们只要把图转置求拓扑排序就可以了

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<queue>
    #include<functional>
    using namespace std;
    
    const int maxn = 222;
    int n,m;
    
    int G[maxn][maxn];
    int in[maxn],arr[maxn];
    void init() {
    	memset(in, 0, sizeof(in));
    	memset(G, 0, sizeof(G));
    }
    
    int main() {
    	int tc;
    	scanf("%d", &tc);
    	while (tc--) {
    		scanf("%d%d", &n, &m);
    		init();
    		for (int i = 0; i < m; i++) {
    			int u, v;
    			scanf("%d%d", &u, &v);
    			G[v][u] = 1;
    		}
    		
    		for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) {
    			if (G[i][j]) {
    				in[j]++;
    			}
    		}
    		vector<int> ans;
    		priority_queue<int> pq;
    		for (int i = 1; i <= n; i++) {
    			if (in[i] == 0) pq.push(i);
    		}
    		while (!pq.empty()) {
    			int u = pq.top(); pq.pop();
    			ans.push_back(u);
    			for (int i = 1; i <= n; i++) {
    				if (G[u][i]) {
    					in[i]--;
    					if (in[i] == 0) pq.push(i);
    				}
    			}
    		}
    		if (ans.size() < n) {
    			printf("-1
    ");
    		}
    		else {
    			reverse(ans.begin(),ans.end());
    			for (int i = 0; i < ans.size(); i++) {
    				arr[ans[i]] = i + 1;
    			}
    			for (int i = 1; i < n; i++) {
    				printf("%d ", arr[i]);
    			}
    			printf("%d
    ", arr[n]);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    flex 自定义事件
    ssis 不停执行的方法
    动态修改大小的Panel用户控件
    ssis 写文件到数据库
    sqlserver CheckSum
    poj1423
    poj1860
    poj1862
    poj1426
    poj1234
  • 原文地址:https://www.cnblogs.com/fenice/p/5631801.html
Copyright © 2020-2023  润新知