zoukankan      html  css  js  c++  java
  • Channel Allocation(四色定理 dfs)

    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 10897   Accepted: 5594

    Description

    When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that every receiver has a strong signal. However, the channels used by each repeater must be carefully chosen so that nearby repeaters do not interfere with one another. This condition is satisfied if adjacent repeaters use different channels.
    Since the radio frequency spectrum is a precious resource, the number of channels required by a given network of repeaters should be minimised. You have to write a program that reads in a description of a repeater network and determines the minimum number of channels required.

    Input

    The input consists of a number of maps of repeater networks. Each map begins with a line containing the number of repeaters. This is between 1 and 26, and the repeaters are referred to by consecutive upper-case letters of the alphabet starting with A. For example, ten repeaters would have the names A,B,C,...,I and J. A network with zero repeaters indicates the end of input.
    Following the number of repeaters is a list of adjacency relationships. Each line has the form:
    A:BCDH
    which indicates that the repeaters B, C, D and H are adjacent to the repeater A. The first line describes those adjacent to repeater A, the second those adjacent to B, and so on for all of the repeaters. If a repeater is not adjacent to any other, its line has the form
    A:
    The repeaters are listed in alphabetical order.
    Note that the adjacency is a symmetric relationship; if A is adjacent to B, then B is necessarily adjacent to A. Also, since the repeaters lie in a plane, the graph formed by connecting adjacent repeaters does not have any line segments that cross. 

    Output

    For each map (except the final one with no repeaters), print a line containing the minumum number of channels needed so that no adjacent channels interfere. The sample output shows the format of this line. Take care that channels is in the singular form when only one channel is required.

    Sample Input

    2
    A:
    B:
    4
    A:BC
    B:ACD
    C:ABD
    D:BC
    4
    A:BCD
    B:ACD
    C:ABD
    D:ABC
    0

    Sample Output

    1 channel needed.
    3 channels needed.
    4 channels needed. 
    题意:类似于染色问题,给定N个顶点的无向图,对这N个顶点染色,要求任意相邻两个顶点染不同的颜色,问最少需要染多少种颜色;

    思路:开始是用的枚举法,把每个节点的度降序排列,每次选一个未被染色的顶点染一种新的颜色,并且不与该顶点相邻的点也染同一种颜色,数据过了,不知道为什么WA;
    后来参考的深搜,对dfs有了更深的了解了;
     1 #include<stdio.h>
     2 #include<string.h>
     3 
     4 int n,map[26][26];
     5 int vis[26][4];//vis[i][j]表示第i个节点被染第j种颜色;
     6 int ans;
     7 
     8 void cmp()
     9 {
    10     int res = -1;
    11     for(int i = 0; i < 4; i++)
    12     {
    13         for(int j = 0; j < n; j++)
    14             if(vis[j][i] && res < i)
    15                 res = i;
    16     }
    17     if(ans > res)
    18         ans = res;
    19 }
    20 void dfs(int x)
    21 {
    22     if(x >= n)
    23     {
    24         cmp();
    25         return;
    26     }
    27     for(int i = 0; i < 4; i++)
    28     {
    29         bool flag = true;
    30         for(int j = 0; j < n; j++)
    31         {
    32             //如果节点x的前驱或后继已经染了第i种色,节点x就不能染i色;
    33             if((map[j][x]&&vis[j][i])||(map[x][j]&&vis[j][i]))
    34             {
    35                 flag = false;
    36                 break;
    37             }
    38         }
    39         if(flag)
    40         {
    41             vis[x][i] = 1;//不满足上个条件,节点x染i色;
    42             dfs(x+1);//继续染下一个节点;
    43             vis[x][i] = 0;
    44         }
    45     }
    46 }
    47 int main()
    48 {
    49     char s[30];
    50     while(~scanf("%d",&n) && n)
    51     {
    52         memset(map,0,sizeof(map));
    53         memset(vis,0,sizeof(vis));
    54         for(int i = 0; i < n; i++)
    55         {
    56             scanf("%s",s);
    57             int u = s[0]-'A';
    58             for(int j = 2; s[j]; j++)
    59             {
    60                 int v = s[j]-'A';
    61                 map[u][v] = 1;
    62             }
    63         }
    64         ans = 5;
    65         vis[0][0] = 1;//假设第一个节点已染第一个色
    66         dfs(1);//从第二个节点开始染色;
    67         ans += 1;
    68         if(ans == 1)
    69             printf("1 channel needed.
    ");
    70         else
    71             printf("%d channels needed.
    ",ans);
    72     }
    73     return 0;
    74 }
    View Code


  • 相关阅读:
    ASP.NET验证控件的使用 拓荒者
    读书笔记:MFC单文档应用程序结构分析 拓荒者
    MFC单文档(SDI)全屏程序的实现 拓荒者
    jQuery的animate函数
    设备尺寸杂谈:响应性Web设计中的尺寸问题
    Yeoman学习与实践笔记
    IE对文档的解析模式及兼容性问题
    推荐给开发和设计人员的iPad应用
    几个移动应用统计平台
    颜色、网页颜色与网页安全色
  • 原文地址:https://www.cnblogs.com/LK1994/p/3273620.html
Copyright © 2011-2022 走看看