• uva10160 Servicing Stations


    The input consists of more than one description of town (but totally, less than ten descriptions). Every
    description starts with number N of towns and number M of pairs of towns directly connected each other. The integers N and M are separated by a space. Every one of the next M rows contains a pair of connected towns, one pair per row. The pair consists of two integers for town's numbers, separated by a space. The input ends with N = 0 and M = 0.
    Output
    For every town in the input write a line containing the obtained minimum.
    Sample Input
    8 12
    1 2
    1 6
    1 8
    2 3
    2 6
    3 4
    3 5
    4 5
    4 7
    5 6
    6 7
    6 8
    0 0
    SampleOutput
          2
    1. 题目大意:给定n个城市,m条无向边分别连接两个城市。若城市x建造了发电厂,则与x相连的城市都有电供应。求使所有城市都有电供应所需的最小发电厂数。
    2. 思路:回溯法+剪枝
    • 可行性剪枝1:若当前已有n个城市有了电,即所有城市都通了电,则记录当前最小值。
    • 可行性剪枝2:若当前搜索到的城市n前面1~n-1编号的城市中有没有通电的,则永远也无法输送电力给那个城市,无解。
    • 剪枝2实现方法:用邻接数组存储每个点相邻的点,将每个邻接数组的点以其编号为关键字降序排序,dfs判断时若前面1~n-1个点中有没有电的,并且它的最大编号儿子的编号小于当前城市(即搜索序更小,已经搜索过却无电),则剪枝。
    • 最优化剪枝:若当前要用的最小发电厂数已经超过了当前求得最有解,则剪枝。
    //顺便注意以下:uva上输入时的“while(scanf("%d%d",&n,&m)&&n&&m)“无法通过,要用”while(scanf("%d%d",&n,&m),n+m)”哦;

    Accepted 660ms (resourse:virtual judge)
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int g[40][40],son[40],n,m,ans;
    bool elt[40];
    bool cmp(const int &a,const int &b)
    {
        return a>b;
    }
    void Init()
    {
        ans=n+1;
        memset(g,0,sizeof(g));
        memset(elt,0,sizeof(elt));
        memset(son,0,sizeof(son));
        for(int i=0; i<m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            g[u][son[u]++]=v;
            g[v][son[v]++]=u;
        }
        for(int i=1; i<=n; i++)
        {
            g[i][son[i]++]=i;
            sort(g[i],g[i]+son[i],cmp);
        }
    }
    void dfs(int cur,int elcity,int sum)
    {
        if(sum>=ans)return;//tree cut 1;
        if(elcity==n)
            ans=sum;
        for(int i=1; i<cur; i++) //tree cut 2;
            if((!elt[i])&&(g[i][0]<cur))
                return;
        dfs(cur+1,elcity,sum);
        int k=0,vis[40];
        for(int i=0; i<son[cur]; i++)
            if(!elt[g[cur][i]])
            {
                elt[g[cur][i]]=1;
                vis[k++]=g[cur][i];
            }
        if(!k)return;//tree cut 3;
        dfs(cur+1,elcity+k,sum+1);
        for(int i=0; i<k; i++)
            elt[vis[i]]=0;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m),n+m)
        {
            Init();
            dfs(1,0,0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    shell内置命令eval的具有什么作用
    openwrt中如何在一个软件包中使能busybox中的工具
    go语言中strings包中的Trim函数的作用是什么
    RedisTemplate的各种操作(set、hash、list、string)
    Spring data redis-StringRedisTemplate 用法
    Spring-data-redis 第一天
    Java操作Redis数据
    BootStrap之X-editable插件使用
    bootstrap editable有默认值
    bootstrap editable初始化后表单
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957716.html
Copyright © 2020-2023  润新知