POJ 3687 Labeling Balls(拓扑排序)

题意:

标号为 1~n 的 N 个球,满足给定的 M 个编号约束关系,输出最终满足关系的球的标号。

思路:

1. 相互之间有一定的约束关系,会联系到拓扑排序,如果利用拓扑排序去解决本题还需要一定的贪心思想;

2. 因为要保证标号小的球靠前的优先级越高,所以对于正向图拓扑排序,无法满足,比如:<1, 4> <4, 2> <3, 5>

3. 对于反向拓扑排序,用同样的方法只需要保证标号大的球尽量靠后就行了,具体见代码。

 

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;



const int MAXN = 210;

vector<int> G[MAXN];

int arr[MAXN], indeg[MAXN];



bool judge(int u, int v) {

    for (int i = 0; i < G[u].size(); i++)

        if (G[u][i] == v) return false;

    return true;

}



int main() {

    int cases;

    scanf("%d", &cases);

    while (cases--) {

        int n, m;

        scanf("%d%d", &n, &m);

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

            G[i].clear(), indeg[i] = 0;

        while (m--) {

            int u, v;

            scanf("%d%d", &v, &u);

            if (judge(u, v)) {

                G[u].push_back(v);

                indeg[v] += 1;

            }

        }

        int w;

        for (w = n; w >= 1; w--) {

            int i;

            for (i = n; i >= 1; i--)

                if (!indeg[i]) break;

            if (i == 0) break;

            

            arr[i] = w;

            indeg[i] = -1;



            for (int j = 0; j < G[i].size(); j++) {

                int v = G[i][j];

                if (indeg[v] > 0) 

                    indeg[v] -= 1;

            }   

        }

        if (w != 0) 

            printf("-1\n");

        else {

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

                printf("%d ", arr[i]);

            printf("\n");

        }

    }

    return 0;

}

你可能感兴趣的:(label)