首页 > 代码库 > POJ--1129--Channel Allocation【顺序着色法】

POJ--1129--Channel Allocation【顺序着色法】

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

题意:当一个广播站向一个很广的地区广播时需要使用中继器,用来转发信号,使得接收器都能收到足够强的信号。然后,每个中继器所使用的频道必须很好的选择,以保证相邻的中继器不会互相干扰。要满足这个条件,相邻中继器必须使用不同的频道。但是频道是很宝贵的,对于一个中继器网络,所使用的频道应当尽量少,现在告诉你中继网络信息,求最少需要使用多少个频道。


思路:根据题目建图,把中继器看做点,有边相连的两个点应当使用不同的频道,所以这是一个平面图顶点着色问题,这类问题并没有有效的算法,顺序着色法用贪心的思想:在给任何一个点着色时,采用其邻接顶点中没有使用的编号最小的颜色


#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 30
#define eps 1e-7
#define INF 0x3F3F3F3F      //0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int u, v, next;
}edge[MAXN * MAXN];
int head[MAXN], cnt, n;
int ans, v_color[MAXN]; //顶点着色数,各顶点的颜色
int color_use[MAXN];    //每种颜色使用的标识,等于1表示这种颜色已使用
void add_edge(int u, int v){
    edge[cnt].u = u;
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}
void greedy(){
    int i, k;
    for(i = 1; i <= n; i++){ //给第i个顶点着色
        memset(color_use, 0, sizeof(color_use));
        for(k = head[i]; k != -1; k = edge[k].next){
            int v = edge[k].v;
            if(v_color[v] != -1)    //邻接顶点v已着色,颜色为v_color[v]
                color_use[v_color[v]] = 1;
        }
        for(k = 1; k <= i; k++){    //k为i的所有邻接顶点中没有使用的编号最小的颜色,编号从1开始
            if(!color_use[k])   break;
        }
        v_color[i] = k; //给当前顶点上色
    }
    for(i = 1; i <= n; i++){
        if(ans < v_color[i])    ans = v_color[i];
    }
}
int main(){
    int i, j;
    char str[500];
    while(scanf("%d", &n), n){
        cnt = 0;
        memset(head, -1, sizeof(head));
        for(i = 0; i < n; i++){
            scanf("%s", str);
            int u = str[0] - 'A' + 1;
            int l = strlen(str);
            for(j = 2; j < l; j++){
                int v = str[j] - 'A' + 1;
                add_edge(u, v);
            }
        }
        ans = 0;
        memset(v_color, -1, sizeof(v_color));
        greedy();
        if(ans == 1)    puts("1 channel needed.");
        else    printf("%d channels needed.\n", ans);
    }
    return 0;
}


POJ--1129--Channel Allocation【顺序着色法】