channel allocation(holding bugs)
开始节点的选取,所选取的节点一定要用所有节点都试一遍。例如
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,在此感谢,希望我的文章也能帮到其他人。