• 【DFS + 四色定理】poj 1129 Channel Allocation


    题目描述:

    http://poj.org/problem?id=1129

     

    中文大意:

    当无线电台在非常大的区域上广播时,需要用到中继器,其作用是重新发信号,使得每个接收器都能接收到较强的信号。

    相邻的中继器需要使用不同的信道,以此来避免二者之间的相互干扰。

    由于射频频谱是一种宝贵的资源,因此中继器网络所需的信道数量越少越好。

    要求编写一个程序,确定一个中继器网络所需的最小信道数。

     

    思路:

    四色定理的变形:任何一张地图,只用四种颜色就能使具有共同边界的国家着上不同的颜色。

    对于每个中继器的信道,都有两种选择:

    ①使用未被相邻中继器使用的信道。 

    ②使用新的信道。

    任选一种,设置为当前中继器的信道,接着设置下一个中继器的信道,以此类推,直至所有中继器的信道设置完毕。

    回溯回来时,设置当前中继器的信道为另外一种,继续执行深搜。

    注意 channel 的单复数问题。

    1 channel needed.
    3 channels needed.

    代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    
    int n;
    string maps[26];
    int channel[26];//各中继器的信道信息 
    int min_k;//最小信道数 
    
    //index:中断器索引 
    //k:当前信道个数 
    void dfs(int index, int k){
        //所有中继器设置完成 
        if(index == n){
            if(min_k > k){
                min_k = k;
            }
            return;
        }
        
        //四色定理:任何一张地图,只用四种颜色就能使具有共同边界的国家着上不同的颜色 
        if(k > 4){
            return;
        }
        
        //检查哪些信道可以使用 
        bool* used = new bool[k]();
        for(int j=0;j<maps[index].size();j++){
            //相邻中继器的索引 
            int beside = maps[index][j] - 'A';
            
            //当前信道已经被使用 
            if(channel[beside] != -1){
                used[channel[beside]] = true;
            }
        }
        
        //两种选择: 
        //1.使用未被相邻中继器使用的信道 
        for(int j=0;j<k;j++){
            if(!used[j]){
                channel[index] = j;
                dfs(index+1, k);
            }
        }
        //2.使用新的信道 
        channel[index] = k;
        dfs(index+1, k+1);
    }
    
    int main(){
        while(cin>>n && n){
            string str;
            for(int i=0;i<n;i++){
                cin>>str;
                int index = str[0] - 'A';
                if(str.size() > 2){
                    maps[index] = str.substr(2);
                }
                else{
                    maps[index] = "";
                }
            } 
            
            min_k = 26;
            memset(channel, -1, sizeof(channel));
            dfs(0, 0);
            
            if(min_k == 1){
                printf("%d channel needed.
    ", min_k);
            }
            else{
                printf("%d channels needed.
    ", min_k);
            }
        }
    } 
    
    //一组测试用例: 
    //10
    //A:BCDEFG
    //B:ACGH
    //C:ABDH
    //D:ACEHJ
    //E:ADFIJ
    //F:AEGI
    //G:ABFHI
    //H:BCDGIJ
    //I:EFGHJ
    //J:DEHI
    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    《c++primer》笔记 第3章 字符串、向量和数组
    如何下载Jason2测高数据
    《c++primer》笔记 第2章 变量和基本类型
    《c++primer》笔记 第1章 开始
    VMware打开vmx文件无响应
    Qt5.6.0连接SQL Server 2008
    Qt5.6.0(32位)编译SQLServer驱动(ODBC)(vs2013)
    Qt中操作数据库例子-插入数据
    《UNIX网络编程卷1》第一例及问题
    UVa 1225 Digit Counting
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14449854.html
Copyright © 2020-2023  润新知