uva10160 Servicing Stations

来源:互联网 发布:网络通信工作原理 编辑:程序博客网 时间:2024/03/29 19:55
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\n",ans);    }    return 0;}


1 0
原创粉丝点击