zoukankan      html  css  js  c++  java
  • 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
    ");
     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("
    ");
     93     }
     94     else
     95     {
     96         printf("1
    1");
     97         for(int i = 1; i < m; i ++)
     98             printf(" 1");
     99         printf("
    ");
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    宿舍局域网的应用
    宿舍无线局域网的组建
    宿舍局域网与Internet连接
    宿舍有线局域网的组建
    设置Windows 远程协助与远程桌面
    家庭局域网接入Internet
    组建Windows家庭组
    OpenGL3D迷宫场景设计
    [Cacti] cacti监控mongodb性能实战
    (视频)《高速创建站点》 4.2 完结篇 – 应用运营vs.发射卫星,遥測(Telemetry) 技术
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11612282.html
Copyright © 2011-2022 走看看