channel allocation(holding bugs)

程序思想:依据四色原理,最多需要四种颜色,本程序中black , blue, green, white就是这四种颜色。从一个点开始,按照节点的名字(A,B,C...)的递增顺序,检查与每个节点连接的各个节点的颜色,排除不能用的颜色,最后为当前节点着上适当的颜色,就这样,一直到检查完所有节点为止。要注意的是:

开始节点的选取,所选取的节点一定要用所有节点都试一遍。例如

6
A:BEF
B:AC
C:BD
D:CEF
E:ADF
F:ADE

如果从A开始着色需要4种颜色;如果从B开始着色则需要3种。

//有一定错误,只能通过poj测试,不能通过joj测试。

#include <iostream>

using namespace std;

//Initially, all nodes' color is black.First,select one node,color it in white.
//Second,select another node,look at whether it is adjacent to the last node,if so
//color it in another color,otherwise,still color it in white.

//1:black,2:blue,3:green,4:white

void GraphInput(char Graph[27][27], int number)
{
    int n;
    n = number;
    for (int i=1; i<=n*2; i++)//因为要存储“:”之前的字母,所以对于
    {                         //每个字母来说要多执行一次for循环,
        char repeater;        //共有n个字母,所以要多循环n次,总共
        cin >> repeater;      //就是2n次
        if (repeater == ':')  //开始存储 图信息
        {
            for (int j=1; ; j++)
            {
                repeater = cin.get();//这里不可以用cin>>register,因为
                if (repeater != '\n')//如果“:”后面是空的话,就不能让
                {                    //cin吃掉":"后面的空格

                // /r 回车符  /n 换行符
                    Graph[i/2][j] = repeater;
                    Graph[i/2][0]++; //用每一行的第0个元素存所连接的节点数
                }
                else
                {
                    break;
                }
            }
        }
    }
}

void Colour(char Graph[27][27], int i, int colour[27])//着色函数
{
    bool black, blue, green, white;
    black = true;//true表示对当前的i节点,该颜色可用
    blue = true;
    green = true;
    white = true;

 for (int j=1; j<=static_cast<int>(Graph[i][0]); j++)  //对Graph[i][0]要记得进行类型转换
    {
  char nodeName = Graph[i][j];                //A,B,C...
        int key = static_cast<int>(nodeName-'A')+1; //1,2,3...
        if (colour[key] == 1)//black                //要注意这里偏移量的计算不要算错
        {
            black = false;
        }
        if (colour[key] == 2)//blue
        {
            blue = false;
        }
        if (colour[key] == 3)//green
        {
            green = false;
        }
        if (colour[key] == 4)//white
        {
            white = false;
        }
    }
    if (black == true)//Black is available.
    {
        colour[i] = 1;
        return;
    }
    if (blue == true) //Blue is available.
    {
        colour[i] = 2;
        return;
    }
    if (green == true)//Green is available.
    {
        colour[i] = 3;
        return;
    }
    if (white == true)//White is available.
    {
        colour[i] = 4;
        return;
    }
}

//核心函数
void Process(char Graph[27][27], int number, int colour[27])
{
    int min = 9999;
    //extern的使用:当用到的函数的定义在当前函数之后,则要
    //用extern 进行外部声明
    extern int ResultOutput(int number, int colour[27]);
    for (int j=0; j<number; j++)//这里是关键:分别把每一个节点作为开始节点,
                                //找到最小的电台数
    {
        for (int i=j+1,k=1; k<=number; i=i%number+1,k++)//不要忘了让i自增而不越界
        {
            Colour(Graph, i, colour);
        }

        if (ResultOutput(number, colour) < min)
        {
            min = ResultOutput(number, colour);
        }
       
        //这里要记得清空colour数组,因为从不同的节点开始的涂色方案
        //可能是不同的。
        for (int i=0; i<27; i++)
        {
            colour[i] = 0;
        }
    }
    if(min == 1)
    {
        cout << "1 channel needed." << endl;
    }
    else
    {
        cout << min << " channels needed." << endl;
    }
}

int ResultOutput(int number, int colour[27])
{
    int n = 0;

    bool black, blue, green, white;
    black = false;
    blue = false;
    green = false;
    white = false;

    for (int i=1; i<=number; i++)
    {
        if (colour[i]==1 && black==false)
        {
            black = true;
            n++;
        }
        if (colour[i]==2 && blue==false)
        {
            blue = true;
            n++;
        }
        if (colour[i]==3 && green==false)
        {
            green = true;
            n++;
        }
        if (colour[i]==4 && white==false)
        {
            white = true;
            n++;
        }
    }
    return n;
}

int main()
{
    char Graph[27][27];
    for (int i=0; i<27; i++)
    {
        for (int j=0; j<27; j++)
        {
            Graph[i][j] = NULL;
        }
    }
    int colour[27] = {0};
    int number = 0;
    cin >> number;
    while (number != 0)
    {
        GraphInput(Graph, number);
        Process(Graph, number, colour);

  //由于之前的程序已经对Graph,colour两个数组有了修改,
  //所以需要清空。要记住,当需要对不同数据做多次相同
  //试验时,一定要恢复“环境变量”,即不同数据要处于同
  //一环境之中。
  int i;
  for(i=0; i<27; i++)
  {
   colour[i] = 0;
  }
  for(i=0; i<27; i++)
  {
   for(int j=0; j<27; j++)
   {
    Graph[i][j] = NULL;
   }
  }
        cin >> number;
    }
    return 0;
}

自己做ACM,测试的时候不妨这样:先按测试平台上的数据顺序测一遍,再逆序测一遍,把文中最结尾的数据测一遍,如果都对,那成功的机会就很大了。
还有要说的就是:做出这道题我也是参考了别人的资料,http://hi.baidu.com/fandywang_jlu/blog/item/a56594c3da55d954b319a8de.html,在此感谢,希望我的文章也能帮到其他人。

posted @ 2011-03-25 21:22  SunnyDay2015  阅读(337)  评论(0编辑  收藏  举报