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

题目大意:给出n个点和m个关系,可以在任何一个点放服务站,如果这个点放了服务站,与它相连得点均可以被服务到,问最少放多少个服务站可以使得所有所有点均可以被服务到。

解题思路:思路很简单,用DFS收索,关键就在与剪枝,我的主要优化在于两个地方。

首先按点得序号开始DFS, cur 表示当前访问得点。

<1>对于每个点,无非就是放与不放(注意这里不能单纯根据这个点有没有被覆盖到去判断该不该放服务站)

<2>第一个剪枝,如果这个点增加服务站之后,被覆盖得点数没有增加,就可以确定当前点是不放(与放得情况相同干嘛要多加一个点)

<3>第二个剪枝,当放得服务站个数大于前面计算的最小值时,剪掉这条路。

<4>第三个剪枝,当出现前面有的点无法被覆盖得时候,可以终止这条路得收索。

这里问解释一下第三个剪枝得情况,比如当前已经访问到第5个点,而1 这点任然没有被覆盖到,而与1 有联系得点2,2 < 5, 说明2 已经被访问过了,说明1 和 2 都没有放服务站,而后面n个点得放与不放都影响不到1 得覆盖状态,所以这条路是无法被满足的。

我在将一下问对优化3的一个小优化,如果按正常的思路,需要开一个数组去记录哪些点放了服务站,然后进行优化3得时候对判断点要去遍历判断点的所有有关系的点是否已经考虑过。而我得做法是将点得关系点排序,每次只需将最大的点与当前访问的点进行比较,大于得话说明这个点还没被确定。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std; #define N 40
int n, m, Min, rec[N];
int g[N][N], son[N]; int cmp(const int &a, const int &b){
return a > b;
} void DFS(int cur, int cnt, int sum){
if (sum >= Min) // 剪枝2:当放得服务站数量大于前面计算的最小值时。
return;
if (cnt == n)
Min = sum; for (int i = 1; i < cur; i++) //剪枝3:出现已经遍历的点无法被覆盖,这条路继续收索是无用功。
if (!rec[i] && g[i][0] < cur)
return;
DFS(cur + 1, cnt, sum); int k = 0, vis[N];
for (int i = 0; i < son[cur]; i++)
if (rec[g[cur][i]] == 0){
vis[k++] = g[cur][i];
rec[g[cur][i]] = 1;
}
if (!k) // 剪枝1:增加覆盖点为0。
return ; DFS(cur + 1, cnt + k, sum + 1); for (int i = 0; i < k; i++) // 回溯要将点还原,不然答案会错。
rec[vis[i]] = 0;
} int main(){
int a, b;
while (scanf("%d%d", &n, &m), n + m){
// Init;
memset(g, 0, sizeof(g));
memset(son, 0, sizeof(son));
memset(rec, 0, sizeof(rec));
Min = n + 1; // Read;
for (int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
g[a][son[a]++] = b;
g[b][son[b]++] = a;
} // Handle;
for (int i = 1; i <= n; i++){
g[i][son[i]++] = i;
sort(g[i], g[i] + son[i], cmp); // 优化3的优化,具体看解释。
}
DFS(1, 0, 0); printf("%d\n", Min);
}
return 0;
}

uva 10160 Servicing Stations(DFS+剪枝)的更多相关文章

  1. UVA 10160 Servicing Stations(深搜 + 剪枝)

    Problem D: Servicing stations A company offers personal computers for sale in N towns (3 <= N < ...

  2. UVA 10160 Servicing Stations(状态压缩+迭代加深)

    [题目链接] LInk [题目大意] 给出一些点和边,选择一个点就能把这个点和相邻的点都覆盖,求最小点覆盖 [题解] 我们压缩点被覆盖的状态,迭代加深搜索覆盖的最小点数, 当剩余的点全部选上时都无法完 ...

  3. UVa 208 消防车(dfs+剪枝)

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

  4. UVA 140 Bandwidth (dfs 剪枝 映射)

    题意: 给定一个n个结点的图G和一个结点的排列, 定义结点i的带宽b(i)为i和相邻结点在排列中的最远距离, 所有b(i)的最大值就是这个图的带宽, 给定G, 求让带宽最小的结点排列. 给定的图 n ...

  5. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  6. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  8. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  9. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

随机推荐

  1. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 G.路径-带条件的树的直径变形-边权最大,边数偶数的树上的最长路径-树形dp

    链接:https://ac.nowcoder.com/acm/contest/558/G 来源:牛客网 路径 小猫在研究树. 小猫在研究路径. 给定一棵N个点的树,每条边有边权,请你求出最长的一条路径 ...

  2. TI科学家谈浮点DSP未来发展

        自十多年前浮点数字信号处理器(DSP)诞生以来,便为实时信号处理提供了算术上更为先进的备选方案.不过,定点器件至今仍是业界的主流.当然低成本是主要原因.定点DSP每器件产品的价格很低,这对大规 ...

  3. Swift2.0语言教程之下标脚本

    Swift2.0语言教程之下标脚本 下标脚本 下标脚本是访问对象.集合或者序列的快速方式.开发者不需要调用实例特定的赋值和访问方法,就可以直接访问所需要的数值.例如在数组中,可以直接使用下标去访问或者 ...

  4. 决策树算法(Bagging与随机森林)

    Bagging算法: 将训练数据集进行N次Bootstrap采样得到N个训练数据子集,对每个子集使用相同的算法分别建立决策树,最终的分类(或回归)结果是N个决策树的结果的多数投票(或平均). 其中,B ...

  5. Markdown的简介(转)

    欢迎使用 Cmd - 在线 Markdown 编辑阅读器 *我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人, Cmd Markdown 是我们给出的答案 -- ...

  6. 关于PyCharm database查看db.sqlites文件无内容的一种可能解决方法

    初学python,学到了scrapy爬虫数据入库,在网上跟着一个视频课进行学习,但是碰到了如下问题: 这里新建了数据库文件之后,将这个.sqlite文件拖动到Database里面,然后出现了上图描述问 ...

  7. PHP 快速排序算法详解

    备注:下面转载的快速排序算法有bug,数组中重复值会被删除,修改后如下: function quickSort($arr){ //递归出口 if(!isset($arr[1])){ return $a ...

  8. iOS录音后播放声音小,AudioSessionInitialize failed,AudioQueueStart failed (-50)

    方法1: UInt32 audioRoute = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty(kAudioSess ...

  9. MYSQL用户操作管理大杂烩

    一.创建用户 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指定该 ...

  10. 从零开始搭建linux下laravel 5.5所需环境(一)

    首先你需要有一台linux服务器,或者虚拟机,这里就不赘述了,不会的可以自行百度. 我这里准备的是一台腾讯云服务器,系统为CentOS 7.4 64位. 你可以使用腾讯云的登录按钮登录到服务器,也可以 ...