poj 2594 Treasure Exploration(最小路径覆盖/二分最大匹配)

Treasure Exploration

Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 7208   Accepted: 2944

Description

Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored treasure? If you never have such experiences, you would never know what fun treasure exploring brings to you.

Recently, a company named EUC (Exploring the Unknown Company) plan to explore an unknown place on Mars, which is considered full of treasure. For fast development of technology and bad environment for human beings, EUC sends some robots to explore the treasure.

To make it easy, we use a graph, which is formed by N points (these N points are numbered from 1 to N), to represent the places to be explored. And some points are connected by one-way road, which means that, through the road, a robot can only move from one
end to the other end, but cannot move back. For some unknown reasons, there is no circle in this graph. The robots can be sent to any point from Earth by rockets. After landing, the robot can visit some points through the roads, and it can choose some points,
which are on its roads, to explore. You should notice that the roads of two different robots may contain some same point.

For financial reason, EUC wants to use minimal number of robots to explore all the points on Mars.

As an ICPCer, who has excellent programming skill, can your help EUC?

Input

The input will consist of several test cases. For each test case, two integers N (1 <= N <= 500) and M (0 <= M <= 5000) are given in the first line, indicating the number of points and the number of one-way roads in the graph respectively. Each of the following
M lines contains two different integers A and B, indicating there is a one-way from A to B (0 < A, B <= N). The input is terminated by a single line with two zeros.

Output

For each test of the input, print a line containing the least robots needed.

Sample Input

1 0
2 1
1 2
2 0
0 0

Sample Output

1
1

2

题意: 一个星球上有n个点,给出几条路,机器人可以沿着路遍历,问要遍历完整个星球最少需要几个机器人
	注意每个点可以重复遍历
思路:最小路径覆盖,二分图最大匹配,和floyd缩点:
	什么叫最小路径覆盖?
    就是说,在当前的图上,找N条路径,让这N条路径覆盖图上所有的点,
	N的最小值就是我们要求的值。根据具体问题的不同,可分为一个顶点只能经过一次,
	和可以经过多次两类。
    最小路径覆盖的算法原理叙述如下:由于每条路径是一串点的序列,
	所以除了终点之外,每个点都有(不一定只有,这是我们等会要讨论的第二类问题。)一个后继,所以我们就用后继为关系建图,把每个点拆为起点和终点。终点放在二分图左侧,起点放在右侧,如果x-y有边,那么就在x的终点和y的起点间连边,求一遍匹配,没有被匹配到的点是干什么的?对,是路径的终点,因为只有路径的终点没有后继,
	所以没有被匹配的点,就是路径的条数。(左为原图,右为建好的二分图)
  那一个点可以经过多次怎么办?如果一个点可以经过多次,Cjf神牛说了:“缩点!”
  缩点完了和上面的做法一样,至于缩点用Floyed。
  二分图最大匹配用匈牙利算法,
   2015,7,24
#include<stdio.h>
#include<string.h>
int path[510][510],vis[510];
int mac[510];
int n,m;
void floyd()
{
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				if(path[i][k]&&path[k][j])
					path[i][j]=1;
			}
}
int Find(int k)
{
	for(int i=1;i<=n;i++)//遍历每个点
	{
		if(!vis[i]&&path[k][i]==1)//如果这个点没有被访问过,而且有路存在
		{
			vis[i]=1;
			if(!mac[i]||Find(mac[i]))//并且这条路没有前驱节点,可以腾出来一个(递归)这可以理解为hdu 2063的对象详见博客
			{
				mac[i]=k;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int i,j,a,b,num;
	while(scanf("%d%d",&n,&m),n+m)
	{
		memset(path,0,sizeof(path));
		for(i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			path[a][b]=1;//注意这是有向图,找了半天错
		}
		floyd();
		num=0;
		memset(mac,0,sizeof(mac));
		for(i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis));
			if(Find(i)) num++;
		}
		printf("%d\n",n-num);
	}
	return 0;
}

时间: 2024-10-25 19:17:29

poj 2594 Treasure Exploration(最小路径覆盖/二分最大匹配)的相关文章

Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)

题目链接: Poj 2594 Treasure Exploration 题目描述: 在外星上有n个点需要机器人去探险,有m条单向路径.问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过. 解题思路: 一眼看上去是普通的最小边覆盖,但是仔细想后发现如果在原图上进行最大匹配的话,每个点只能经过一次.这样的话对于本题求出的并不是最优解,所以我们要先对原图进行传递闭包处理,然后再进行最大匹配. 这个题目点数太少H_K和匈牙利算法在空间和时间上并没有什么差,就代码复杂度而言匈牙利算法更有优

POJ 2594 传递闭包的最小路径覆盖

Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7171   Accepted: 2930 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored

POJ 2594 (传递闭包 + 最小路径覆盖)

题目链接: POJ 2594 题目大意:给你 1~N 个点, M 条有向边.问你最少需要多少个机器人,让它们走完所有节点,不同的机器人可以走过同样的一条路,图保证为 DAG. 很明显是 最小可相交路径覆盖 问题.要先通过闭包建图后,再当作 最小不可交路径覆盖 问题 求解即可. 原因: 与 最小不可交路径覆盖 问题不同的是,两个机器人可以走相同的边,在最小覆盖的基础上如果还要走过相同的边,那么说明后一个机器人到达某一个未被走过的节点时,必须要经过某一条路,即已经走过的这条路. 比如,前一个机器人已

POJ 2594 Treasure Exploration(最小路径覆盖变形)

POJ 2594 Treasure Exploration 题目链接 题意:有向无环图,求最少多少条路径能够覆盖整个图,点能够反复走 思路:和普通的最小路径覆盖不同的是,点能够反复走,那么事实上仅仅要在多一步.利用floyd求出传递闭包.然后依据这个新的图去做最小路径覆盖就可以 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using names

poj 2594 Treasure Exploration (二分匹配)

Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 6558   Accepted: 2644 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored

poj 3020 Antenna Placement (最小路径覆盖)

链接:poj 3020 题意:一个矩形中,有n个城市'*','o'表示空地,现在这n个城市都要覆盖无线,若放置一个基站, 那么它至多可以覆盖本身和相邻的一个城市,求至少放置多少个基站才能使得所有的城市都覆盖无线? 思路:求二分图的最小路径覆盖(无向图) 最小路径覆盖=点数-最大匹配数 注:因为为无向图,每个顶点被算了两次,最大匹配为原本的两倍, 因此此时最小路径覆盖=点数-最大匹配数/2 #include<stdio.h> #include<string.h> int edge[4

BZOJ 2150 部落战争 最小路径覆盖 二分图最大匹配

题目大意:给出一张地图,一个军队要征战整个土地.一块土地只能经过一次,有X的地方不能走,军队只会走R*C个格子,只会向下走,问最少需要多少军队能够征战所有的土地. 思路:这个是前几天考试的题,今天居然发现时BZ的原题,还好当时A掉了... 看到每个土地只能经过一次就想到了网络流什么的,再一想想好像是最小路径覆盖啊,然后拆点,建图,Hungary,二分图最小路径覆盖=点数-最大匹配,没了.. CODE: #include <cstdio> #include <cstring> #in

luogu 2764 最小路径覆盖问题 | 最大匹配

luogu 2764 最小路径覆盖 = n - 最大匹配 1 #include <cstdio> 2 #include <string> 3 #include <vector> 4 #include <queue> 5 #include <cstring> 6 7 const int N = 200, INF = 0x3f3f3f3f; 8 9 int read() { 10 int x = 0, f = 1; 11 char c = getch

POJ 2594 —— Treasure Exploration——————【最小路径覆盖、可重点、floyd传递闭包】

Treasure Exploration Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2594 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploratio