UVA - 10160 Servicing Stations(回溯+剪枝)
来源:互联网 发布:建党伟业 知乎 编辑:程序博客网 时间:2024/04/19 20:28
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.
InputThe 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
题目大意:一个公司销售个人电脑,在n个城镇建立服务站,n个城镇有m条道路,每个服务可以服务但前的城镇,和当前城镇相连接的城镇,问最少要建立多少个服务站?
解析:本题采用回溯法,但是单纯的只回溯不剪枝会超时,因为最多有35个城镇,即要枚举2^35中情况,可想而知会超时。
所以这题的做法是建立临接表来保存两节点连接
有4个剪枝:
1、当前的服务站个数大于原先的答案,显然后面只会变大,返回。
2、当前已经覆盖的结点等于n即全部覆盖了,那么返回答案,出口。
3、如果当前枚举的点编号大于n返回。
4、最重要,最难想到的一个剪枝,当出现前面有的已经无法被覆盖,那么后面不可能再覆盖这个点,返回。
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 36;int n,m;int edge[N][N];int vis[N];int s[N];int ans;void dfs(int u,int sum,int cur) {if(cur == n && sum < ans) {ans = sum;return;}if(u > n || sum >= ans) {return;}for(int i = 1; i < u; i++) {if( !vis[i] && edge[i][s[i]-1] < u) {return ;}}int cnt = 0;for(int i = 0; i < s[u]; i++) {if( !vis[edge[u][i]] ) {cnt++;}vis[edge[u][i]]++;}if(cnt) {dfs(u+1,sum+1,cur+cnt);}for(int i = 0; i < s[u]; i++) {vis[edge[u][i]]--;}dfs(u+1,sum,cur);}int main() {int u,v;while(scanf("%d%d",&n,&m) != EOF && (n || m)) {memset(edge,0,sizeof(edge));memset(s,0,sizeof(s));memset(vis,0,sizeof(vis));for(int i = 0; i < m; i++) {scanf("%d%d",&u,&v);edge[u][s[u]++] = v;edge[v][s[v]++] = u;}for(int i = 1; i <= n; i++) {edge[i][s[i]++] = i;sort(edge[i],edge[i]+s[i]);}ans = n;dfs(1,0,0);printf("%d\n",ans);}return 0;}
- UVA - 10160 Servicing Stations(回溯+剪枝)
- UVA - 10160 Servicing Stations 剪枝+回溯
- [UVA 10160] Servicing Stations (DFS回溯 + 剪枝)
- Servicing stations +uva+回溯+剪枝
- uva 10160 Servicing Stations(DFS+剪枝)
- UVA 10160 Servicing Stations(深搜 + 剪枝)
- UVa 10160 - Servicing Stations
- uva 10160 Servicing Stations
- UVA 10160 - Servicing Stations
- uva 10160 Servicing stations
- uva 10160Servicing Stations
- UVA 10160 Servicing Stations
- UVa 10160 - Servicing Stations
- UVa Problem 10160 Servicing Stations (服务站)
- 10160 - Servicing Stations(TLM)
- UVa 10160 Servicing stations解题报告
- Servicing Stations
- (挑战编程_8_4)Servicing Stations
- 黑马程序员------javaBean
- Android 为百度map缩放设置自定义的缩放范围ZoomLevel(个人)
- jquery全局变量3中方式:var test=5;function(){test=5;};window.test=5;
- Java 动态编译的一点理解
- 告诉你一个真实的中国互联网:精英与草根
- UVA - 10160 Servicing Stations(回溯+剪枝)
- 编程之美--数组循环移位
- Andriod学习之路
- 通过shell批量删除多个目录下面的子目录
- 初试hibernate4.3.6
- oracle blob字段转为varchar2
- android自定义日历控件
- 大明A+B hdu acm 1753 c++
- HDU 4176 Class Statistics