UVa 10160 Servicing Stations
A Company offers personal computers for sale in n towns (3 <= N <= 35). The towns is denoted by 1, 2, ..., N. There is direct routes connecting M pairs from among these towns. The company decides-to-build servicing stations in several towns, so-for-all town X, there would is a station located Either in X or in some immediately neighbouring town of X.
A company that offers a PC sells computers in N towns (3<= n<=35). Towns are recorded as 1,2,...,n, and the towns are connected by M-paths. The company decided to set up a service station in several towns, so that for any town x, there would be a service station in X or in some towns directly adjacent to X.
Write a finding out the minumum number of stations, which the company have to build, so, the above conditio N holds.
Write a program to find the minimum number of service stations that meet the requirements.
Input
Enter the input consists of more than one description in town (but totally, less than ten descriptions). Every description starts with number N of towns and number M of pairs in towns directly connected each other. The integers N and M is 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 the integers for town's numbers, separated by a space. The input ends with N = 0 and M = 0.
The data entered is made up of several sets of descriptions of the town (though the total will not exceed 10 groups). Each group of data is first the number of towns N and the number of roads m. Between N and M is separated by a space. Each row of the next M row gives a pair of towns, indicating that there is a road between the two towns, separated by a space between each of the two towns. Ends when N=0 and m=0.
Output
Output for every, the input write a line containing the obtained minimum.
The output can cover the minimum number of service stations in all towns. 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
This is a search problem from the programming challenge, but also a relatively good written deep search. The basic idea is to think about it, just start the enumeration from the first point, until all the points are covered and find the optimal solution. But if such a naked search, 35 of the range is bound to explode, so consider some pruning.
The first thing you can find is that if you build a service station at a certain point, the number of points that can be covered does not increase, then we might as well not put it.
Then, if one way halfway, it is found that the number of service stations set at this time is greater than or equal to the current optimal solution, then this road can be cut.
Further thinking can also be found, if at the time of initialization, each point can be covered by the number of points from small to large sorting, then in the next deep search, if the current point is found, the number is less than the current point and no covered points can lead to the point of the maximum number of points is less than the number of the current point, Then you can give up the road, because it is impossible to continue to search the point of coverage. Practice has proved that to do these three pruning can be a, but there are several optimizations can be used (a after the thought out, too lazy to realize the 0.0 .... ):
1. If a point a can lead to a point of only one point B, then the B point must be built a service station. If a point does not have a point that leads to it, a service station must be built at that point.
2. You can dynamically modify each point at this time after each build station to the number of points that are not yet covered, and then prioritize the points that lead to points that are not yet covered, so that the best solution can be found more quickly based on the pruning above.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N-Using
namespace Std;
int N,m,minn;
int a[n][n],f[n],c[n]; BOOL CMP (const int &X,CONST int &y) {return x>y;} void put (int x,int k,int s) {if (K==n && S<mi
nn) minn=s;
if (S>=minn) return;
for (int i=1; i<=x; i++) if (!f[i] && x>a[i][1]) return;
Put (x+1,k,s);
int v=0,b[n];
for (int i=1; i<=c[x]; i++) if (!f[a[x][i]]) {f[a[x][i]]=true;
B[++v]=a[x][i];
} if (!v) return;
else s++,k+=v;
Put (x+1,k,s);
for (int i=1; i<=v; i++) F[b[i]]=false;
} int main () {while (scanf ("%d%d", &n,&m) ==2) {if (!n &&!m) break;
minn=n+1;
memset (A,0,sizeof (a));
Memset (C,0,sizeof (c));
memset (F,false,sizeof (f));
for (int i=1; i<=m; i++) {int x, y;
scanf ("%d%d", &x,&y);
A[x][++c[x]]=y;
A[y][++c[y]]=x;
} for (int i=1; i<=n; i++) {a[i][++c[i]]=i; Sort (A[i]+1,a[i]+c[i]+1,CMP);
} put (1,0,0);
printf ("%d\n", Minn);
} return 0; }