ZOJ-1084-Channel Allocation

博客围绕转发器网络频道最小使用量问题展开。任务是根据转发器网络描述信息求所需频道最小使用量,该网络相当于无向图,问题转化为无向图着色问题,最多需4种颜色。算法是先判断结点数,再依次用2和3求解,不行则结果为4,着色用深度优先搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1084

任务:根据读取的转发器网络的描述信息,求出所需频道的最小使用量

算法分析:本题的转发器网络相当于一个无向图,临近的转发器使用不同的频道相当于无向图的着色问题。相对此题最多需要4中颜色。

当只有一个结点时,只需一种颜色。

否则依次用2和3去求解,如果可以成功,则为求解结果,否则最后结果为4

着色用深度优先搜索进行

View Code
#include<stdio.h>
#include<string.h>

int n,map[27][27],used[27];

int dfs(int id,int color)
{
    int i,j,flag;
    for(i=1;i<=color;i++)
    {
        used[id]=i;    //对结点id着色为i
        flag = 1;
        for(j=1;j<id;j++)
        {
            if(map[j][id]&&used[j]==used[id])//改颜色已经使用过了
            {
                flag = 0;    break;
            }
        }
        //改颜色有效,当所有结点着色完毕返回true,或者给下一个结点着色
        if(flag && (id == n || dfs(id+1,color)))
            return 1;
    }
    return 0;
}

int main()
{
    char str[30];
    int i,j,one;
    while(scanf("%d",&n)!=EOF&&n)
    {
        one = 1;
        memset(map,0,sizeof(map));
        for(i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(j=2;str[j];j++,one = 0)
                map[i][str[j]-'A'+1] = map[str[j]-'A'+1][i] = 1;
        }
        used[1]=1;
        if(one)    printf("1 channel needed.\n");
        else if(dfs(2,2))    printf("2 channels needed.\n");
        else if(dfs(2,3))    printf("3 channels needed.\n");
        else printf("4 channels needed.\n");
    }
    return 0;
}
View Code
#include<stdio.h>
#include<string.h>

int n,map[27][27],used[27];
int flag;
void dfs(int id,int color)
{
    if(id>n)
    {
        flag = 1;    return ;
    }
    if(!flag)
    {
        int i,j,ok;
        for(i=1;i<=color;i++)
        {
            used[id]=i;    ok = 1;
            for(j=1;j<id;j++)
            {
                if(map[j][id]&&used[j]==used[id])
                {
                    ok = 0;        break;
                }
            }
            if(ok)    dfs(id+1,color);
        }
    }
}

int main()
{
    char str[30];
    int i,j,one;
    while(scanf("%d",&n)!=EOF&&n)
    {
        one = 1;
        memset(map,0,sizeof(map));
        for(i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(j=2;str[j];j++,one = 0)
                map[i][str[j]-'A'+1] = map[str[j]-'A'+1][i] = 1;
        }
        used[1]=1;
        flag = 0;
        if(one)    printf("1 channel needed.\n");
        else
        {
            dfs(2,2);
            if(flag)    printf("2 channels needed.\n");
            else
            {
                dfs(2,3);
                if(flag)    printf("3 channels needed.\n");
                else printf("4 channels needed.\n");
            }
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/pcoda/archive/2012/09/02/2667933.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值