POJ 3687 Labeling Balls 逆向建图,拓扑排序

题目链接: http://poj.org/problem?id=3687

要逆向建图,输入的时候要判重边,找入度为0的点的时候要从大到小循环,尽量让编号大的先入栈,输出的时候注意按编号的顺序输出重量,不是按重量大小输出编号。。

题目确实很简单,但是感觉很经典。

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <stack>

 4 using namespace std;

 5 bool graph[210][210], vis[210];

 6 int n, m, indegree[210], weight[210];

 7 stack<int>s;

 8 

 9 bool toposort()

10 {

11     while(!s.empty())s.pop();

12     memset(vis, 0, sizeof(vis));

13     int cnt = 0;

14     for(int i = 0; i < n; i++)

15     {

16         for(int j = n; j >= 1; j--)

17         {

18             if(indegree[j] == 0 && !vis[j])

19             {

20                 cnt++;

21                 s.push(j);

22                 vis[j] = 1;

23                 for(int k = 1; k <= n; k++)

24                 {

25                     if(graph[j][k])

26                         indegree[k]--;

27                 }

28                 break;

29             }

30         }

31     }

32     return cnt == n;

33 }

34 

35 void solve()

36 {

37     int w = 1;

38     while(!s.empty())

39     {

40         int u = s.top();

41         s.pop();

42         weight[u] = w++;

43     }

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

45         printf("%d ", weight[i]);

46     printf("%d\n", weight[n]);

47 }

48 

49 int main()

50 {

51     int t, u, v;

52     scanf("%d", &t);

53     while(t--)

54     {

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

56         memset(graph, 0, sizeof(graph));

57         memset(indegree, 0, sizeof(indegree));

58         for(int i = 0; i < m; i++)

59         {

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

61             if(!graph[v][u])

62             {

63                 graph[v][u] = 1;

64                 indegree[u]++;

65             }

66         }

67         if(toposort())

68             solve();

69         else printf("-1\n");

70     }

71     return 0;

72 }
View Code

 

你可能感兴趣的:(label)