Coloring Edges 【拓扑判环】

题目链接:https://vjudge.net/contest/330119#problem/A

题目大意:

1.给出一张有向图,给该图涂色,要求同一个环里的边不可以全部都为同一种颜色。问最少需要多少颜色,并输出各边的涂色。

解题思路:

1.多画几张图就发现,颜色种类只会是1或者2。当不存在环的时候,全部涂1。当存在环的时候,环中可以分成两种边(小节点指向大节点涂1,大节点指向小节点涂2),就会发现所有的环颜色一定不会全部相同。

2.思考过1就发现这道题只需要判断是否存在环即可。可以用拓扑判断。原理为:在拓扑的过程中,入度为0的点会入队,但由于环上各点入度不可能为0.因此无法入队。所以在拓扑结束后,还存在没有入队的点,即存在环。

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #define mem(a, b) memset(a, b, sizeof(a))
  5 const int MAXN = 5100;
  6 const int MAXM = 5100;
  7 using namespace std;
  8 
  9 int n, m;
 10 int head[MAXN], cnt, in[MAXN], out[MAXN], tot;
 11 queue<int> Q;
 12 
 13 struct Edge
 14 {
 15     int from, to, next;
 16 }edge[MAXM];
 17 
 18 void add(int a, int b)
 19 {
 20     cnt ++;
 21     edge[cnt].from = a;
 22     edge[cnt].to = b;
 23     edge[cnt].next = head[a];
 24     head[a] = cnt;
 25 }
 26 
 27 int topo()
 28 {
 29     for(int i = 1; i <= n; i ++)
 30     {
 31         if(!in[i])
 32         {
 33             Q.push(i);
 34             tot ++;
 35         }
 36     }    
 37     while(!Q.empty())
 38     {
 39         int temp = Q.front();
 40         Q.pop();
 41         for(int i = head[temp]; i != -1; i = edge[i].next)
 42         {
 43             int to = edge[i].to;
 44             in[to] --;
 45             if(!in[to])
 46             {
 47                 Q.push(to);
 48                 tot ++;
 49             }
 50         }
 51     }
 52     if(tot != n) //存在 点 没有入队 
 53         return 1;
 54     else
 55         return 0;
 56 }
 57 
 58 int main()
 59 {
 60     scanf("%d%d", &n, &m);
 61     mem(head, -1);
 62     for(int i = 1; i <= m; i ++)
 63     {
 64         int a, b;
 65         scanf("%d%d", &a, &b);
 66         in[b] ++, out[a] ++;
 67         add(a, b); 
 68     }
 69     if(topo()) //判是否有环存在
 70     {
 71         printf("2\n");
 72         int flag = 1;
 73         for(int i = 1; i <= cnt; i ++)
 74         {
 75             int a = edge[i].from, b = edge[i].to;
 76             if(flag)
 77             {
 78                 if(a < b)
 79                     printf("1");
 80                 else
 81                     printf("2");
 82                 flag = 0;
 83             }
 84             else
 85             {
 86                 if(a < b)
 87                     printf(" 1");
 88                 else
 89                     printf(" 2");
 90             }
 91         }
 92         printf("\n");
 93     }
 94     else
 95     {
 96         printf("1\n1");
 97         for(int i = 1; i < m; i ++)
 98             printf(" 1");
 99         printf("\n");
100     }
101     return 0;
102 }
View Code

 

posted @ 2019-09-30 13:03  缘未到  阅读(279)  评论(0编辑  收藏  举报