博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(hdu step 6.3.1)Strategic Game(求用最少顶点数把全部边都覆盖,使用的是邻接表)
阅读量:7221 次
发布时间:2019-06-29

本文共 3439 字,大约阅读时间需要 11 分钟。

题目:

Strategic Game

Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 110 Accepted Submission(s): 75
 
Problem Description
Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?
Your program should find the minimum number of soldiers that Bob has to put for a given tree.
The input file contains several data sets in text format. Each data set represents a tree with the following description:
the number of nodes
the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0)
The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.
For example for the tree: 
 
the solution is one soldier ( at the node 1).
The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:
 
 
 
Sample Input
40:(1) 11:(2) 2 32:(0)3:(0)53:(3) 1 4 21:(1) 02:(0)0:(0)4:(0)
 
Sample Output
12
 
 
Source
Southeastern Europe 2000
 
Recommend
JGShining

题目分析:

               二分图,求最小顶点覆盖。简单题。这道题须要注意的是,用邻接矩阵来做会超时,数组开得太大,要用

邻接表来做。

最小顶点覆盖 = 最大匹配数/2

代码例如以下:

/* * a.cpp * *  Created on: 2015年3月13日 *      Author: Administrator */#include 
#include
#include
#include
using namespace std;const int maxn = 1501;//bool map[maxn][maxn];//这个是使用邻接矩阵实现时所须要用到的数据结构vector
map[maxn];//这个是使用邻接表实现时所须要用到的数据结构.这时候map[i]里面村的就是愿意和结点i匹配的结点集合了bool useif[maxn];//用于标记某个节点是否已经匹配int link[maxn];//link[i] = t .表示结点i匹配的结点是tint n;//节点数/** * 用邻接表实现的,推断结点t能否找到匹配的节点 */bool can(int t){ int i; int size = map[t].size();//获取元一个结点t匹配的结点的个数 for(i = 0 ; i < size ; ++i){//遍历每个愿意和结点t匹配的结点 int index = map[t][i];//获取愿意和节点t匹配的结点的序号 if(useif[index] == false){//假设该节点还没有匹配 useif[index] = true;//将该节点标记为已经匹配 if(link[index] == - 1 || can(link[index])){//假设该节点还没有匹配的结点||该匹配结点能找到其它的匹配结点 link[index] = t;//那么僵该节点的匹配结点设置为t return true;//返回true,表示可以t找到匹配的结点 } } } return false;//返回false,表示结点t无法找到匹配的节点}/** * 求最大匹配数 */int max_match(){ int num = 0; int i; for(i = 0 ; i < n ; ++i){//遍历全部节点,求最大匹配数 memset(useif,false,sizeof(useif)); if(can(i) == true){ num++; } } return num;}int main(){ while(scanf("%d",&n)!=EOF){// memset(map,false,sizeof(map));//使用邻接矩阵实现求最大匹配数时,清空map的写法 int i; for(i = 0 ; i < n ; ++i){//使用邻接矩阵求最大匹配数时,清空map的写法 map[i].clear(); } memset(link,-1,sizeof(link)); int a,b; for(i = 0 ; i < n ; ++i){ scanf("%d:(%d)",&a,&b); int c; int j; for(j = 0 ; j < b ; ++j){ scanf("%d",&c);// map[a][c] = true;//邻接矩阵建立关系的写法// map[c][a] = true; /** * 这道题和Grils And Boys 的差别就在于 * 假设0 (2): 1 2 --->这个表示0与1和2相互认识 * 在Grils And Boys中,0会出如今1和2的描写叙述中如 * 1 (...): 0 ... * 2 (...): 0 ... * * 可是这道题中0 (2): 1 2 表示的不过0认识1和2 * 但1和2不一定认识0. * 在做的时候我们要把它转换成相互认识来做 */ map[a].push_back(c);//邻接表建立关系的写法 map[c].push_back(a); } } //最小顶点覆盖 = 最大匹配数/2 printf("%d\n",max_match()/2); } return 0;}

转载地址:http://gixym.baihongyu.com/

你可能感兴趣的文章
redis:Sentinel高可用方案
查看>>
Linux 系统故障排除
查看>>
我的友情链接
查看>>
Mysql汉子转拼音
查看>>
设置MySQL数据库超时
查看>>
一致性hash算法
查看>>
lua + redis 的去重队列
查看>>
web负载均衡(ipvsadm)(未成)
查看>>
抓取存储quota超过80%的users
查看>>
C语言经典算法100例
查看>>
速成CAD版本转换的教程
查看>>
CAD文件图纸过大,该怎么解决?
查看>>
Spring aop 切不进去原因。。
查看>>
PHP获取客户端IP
查看>>
php开发APP接口-封装通信接口改进版
查看>>
Android系统性能演变历程
查看>>
OSChina 周三乱弹 —— 打醒精神去瞌睡
查看>>
SSH 密钥登录linux
查看>>
你必须掌握的 21 个 Java 核心技术!
查看>>
告诉你WHT中文站是什么?
查看>>