uva 10160 Servicing Stations

来源:互联网 发布:轻淘客和淘宝联盟 编辑:程序博客网 时间:2024/04/26 20:12

题目地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1101

题目描述:

Problem D: Servicing stations


A company offers personal computers for sale in N towns (3 <= N <= 35). The towns are denoted by 1, 2, ..., N. There are direct routes connecting M pairs from among these towns. The company decides to build servicing stations in several towns, so that for any town X, there would be a station located either in X or in some immediately neighbouring town of X.

Write a program for finding out the minumum number of stations, which the company has to build, so that the above condition holds.

Input 
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.

An example:

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

Output:

2


题意:最小支配集问题,或者说发电站,在一个城市放发电站,这个城市和直接邻接城市都会有电。问使所有城市都有电的最小放置发电站的个数。

题解:一、DFS+剪枝 二、DFS+状态压缩+剪枝

一:

首先想到DFS,城市就是两种状态放发电站 还是  不放发电站 如此深搜下去可以得到最小的放置发电站个数,但35的数据规模是不允许不剪枝的。

配合上面的DFS剪枝,目前想到的就三个:

1、放置发电站后,其产生的作用为0,即放置这个发电站后,有电的城市还是有电,没电的城市还是没电,也就是说放置发                                                                                  电站后,状态从无电变为有电的城市为0。(注意,有电的城市是可以重复有电的,即被多家不同的邻接发电站供电,放置       发电站的城市也可以是有电的,只要城市本身没有发电站就行)这样的情况剪掉不再深搜下去。

2、记录每一种成功的能覆盖全城市的发电站放置个数(但不一定是最优的),再以后的其他情况放置的搜索过程中,若当前       的发电站放置个数已经大于记录里保存的成功覆盖城市的发电站个数,直接将这种搜索情况剪掉(因为再搜下去,只会       比记录里的大根本不可能是最优解)。

3、在深搜到某一点时,他之前存在着没有电的点,而这个某一点之后的其他点即我们后面要搜到的点也没有与前面的这个无电的点直接邻接连通,那么意味着这趟搜索直到结束,这个无电的点也永远无电(不能再在这个城市放发电站,因为搜      索过程已经到后面的点;也不能通过后续的点放发电站对他供电因为根本不直接连通邻接),显然不能满足覆盖全城市有     电的条件,剪掉这种情况。

代码:

/*three prunes for this DFS(maybe not for only 3)1.place this station but no any different from  before,that is to say  the act is not increased2.save the succeed MinSta,if the other DFSs the StaNum>MinSta then we need not DFS this case3.if we DFS the cur  but the 1~cur have the unactivity node and cur ~ n have no cnnect to this unactivity node,so this node would be unactivity forever so we prune it*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <iostream>#include <algorithm>using namespace std;int N=0,M=0;//undirected graph  N vertex  M edgesint StaNum=0;//number of stationint MinSta=0;// min number of stationbool Graph[35+5][35+5]={false};//begin with 1int StaTo[35+5]={0};//the status of the towns,begin with 1,ths stato[i]++ it's value can be cover and repeatint act=0;//act is activity number of the townsint PointDegree[35+5]={0};//save the point's degree/*DFS the graph*/int DFS(int cur){//2 pruneif(StaNum>MinSta){return(0);}if(cur>N){if(act==N){if(StaNum<MinSta){MinSta=StaNum;}}}else{//3 pruneint i=0,j=0;for(i=1;i<=cur-1;i++){if(StaTo[i]==0){for(j=cur;j<=N;j++){if(Graph[i][j]){break;}}if(j>N){return(0);//the point i would be unactivity forever}}}int oldact=act;//place the sourceif(StaTo[cur]==0)act++;StaTo[cur]++;StaNum++;//activate the neighbourfor(i=1;i<=N;i++){if(Graph[cur][i]){if(StaTo[i]==0){act++;}StaTo[i]++;}}if(act>oldact)//1 pruneDFS(cur+1);for(i=1;i<=N;i++){if(Graph[cur][i]){StaTo[i]--;if(StaTo[i]==0){act--;}}}StaNum--;StaTo[cur]--;if(StaTo[cur]==0){act--;}//don't place the sourceDFS(cur+1);}return(0);}/*for test*/int test(){return(0);}/*main process*/int MainProc(){while(scanf("%d%d",&N,&M)!=EOF&&(N+M)>0){//initmemset(Graph,false,sizeof(Graph));memset(StaTo,0,sizeof(StaTo));memset(PointDegree,0,sizeof(PointDegree));MinSta=100;StaNum=0;act=0;int toStart=0,toEnd=0;int i=0;int MaxDegree=0;int MaxIndex=0;for(i=1;i<=M;i++){scanf("%d%d",&toStart,&toEnd);Graph[toStart][toEnd]=true;Graph[toEnd][toStart]=true;}DFS(1);printf("%d\n",MinSta );}return(0);}int main(int argc, char const *argv[]){/* code */MainProc();return 0;}




原创粉丝点击