POJ 2594--Treasure Exploration【二分图 && 最小路径覆盖 && 点可以重复走 && 传递闭包】

Treasure Exploration

Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 7343   Accepted: 3002

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

题意:

派机器人去火星寻宝,给出一个无环的有向图,机器人可以降落在任何一个点上,再沿着路去其他点探索,我们的任务是计算至少派多少机器人就可以访问到所有的点。有的点可以重复去。

解析:这题粗略一看,有点最小路径覆盖的意思,但是和标准的最小路径覆盖问题不同在于,标准的最小路径覆盖问题是每个点只能走一次,本题的点是可以重复去走了。

但是我们可以转化一下,传递闭包建立新图,转化为标准的路径覆盖。最小路径覆盖 = 图的顶点数 – 最大匹配数。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 550
using namespace std;
int map[maxn][maxn];
int used[maxn];
int link[maxn];
int n, m;

void init(){
    memset(map, 0, sizeof(map));
}

void getmap(){
    while(m--){
        int a, b;
        scanf("%d%d", &a, &b);
        map[a][b] = 1;
    }
}

void floyd(){
    for(int k = 1; k <= n; ++k)
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                map[i][j] = map[i][j] || map[i][k] && map[k][j];
}

bool dfs(int x){
    for(int i = 1; i <= n; ++i){
        if(map[x][i] && !used[i]){
            used[i] = 1;
            if(link[i] == -1 || dfs(link[i])){
                link[i] = x;
                return true;
            }
        }
    }
    return false;
}

int hungary(){
    int ans = 0;
    memset(link, -1, sizeof(link));
    for(int i = 1; i <= n; ++i){
        memset(used, 0, sizeof(used));
        if(dfs(i))
            ans++;
    }
    return ans;
}

int main (){
    while(scanf("%d%d", &n, &m), n || m ){
        init();
        getmap();
        floyd();
        int sum = hungary();
        printf("%d\n", n - sum);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 20:35:58

POJ 2594--Treasure Exploration【二分图 && 最小路径覆盖 && 点可以重复走 && 传递闭包】的相关文章

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

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

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

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

poj 2594 Treasure Exploration(最小路径覆盖,可重点)

题意:选出最小路径覆盖图中所有点,路径可以交叉,也就是允许路径有重复的点. 分析:这个题的难点在于如何解决有重复点的问题-方法就是使用Floyd求闭包,就是把间接相连的点直接连上边,然后就是求最小路径覆盖了.我来大概解释一下为什么是对的,首先我们要明确,当我们重复利用一个点的时候,一定是有两个比较良好的路径相交了,而二分图是不允许这样的情况存在的,因为那必然存在了一个点有一个以上的出度或者入度了,而怎么避免这个问题呢,看下面的图: 这就是针对这个问题的一个典型的模型,如果使用正常二分图,求得的匹

POJ - 3216 Repairing Company 二分图 最小路径覆盖

题目大意:有一个人开了一间维修店.某天,该维修店接收到了Q个任务,这Q个任务分布在M个城市中.每个任务有三个值,分别是所在城市,起始时间,维修时间. 现在给出M个城市的路线图,路线对应的是从某城市到某城市的所需时间. 问至少要派多少个维修人员才能完成这Q个任务 解题思路:现将能联通的城市联通起来,用floyd求出城市之间的时间数 接着就要找关系了,如果 起始时间 + 维修时间 + 两个城市来往的时间 <= 另外一个任务的起始时间 就表示该任务做完后可以接着做下一个任务,这样关系就明确了 现在要求

POJ - 3020 Antenna Placement 二分图 最小路径覆盖

题目大意:有n个城市,要在这n个城市上建立无线电站,每个无线电站只能覆盖2个相邻的城市,问至少需要建多少个无线电站 解题思路:英语题目好坑,看了半天.. 这题和POJ - 2446 Chessboard类似 可以将所有城市分成两个点集,那么之间的连线就代表无线电站的覆盖关系了. 因为所有城市都要覆盖到,所以根据关系,求出最小路径覆盖就能覆盖所有城市了 #include<cstdio> #include<algorithm> #include<cstring> #incl

POJ2594 Treasure Exploration(最小路径覆盖+传递闭包)

题意: 派机器人去火星寻宝,给出一个无环的有向图,机器人可以降落在任何一个点上, 再沿着路去其他点探索,我们的任务是计算至少派多少机器人就可以访问到所有的点.点可以重复去. 思路: 最小路径覆盖,只是点可以重复去,就需要求传递闭包,用floyd /* *********************************************** Author :devil Created Time :2016/5/17 16:45:13 *****************************

poj 2594 Treasure Exploration 二分图匹配

点击打开链接题目链接 Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7215   Accepted: 2947 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you eve

POJ - 2594 Treasure Exploration 二分图匹配 + floyd

题目大意:在火星上有N个矿,有点矿之间存在着一条路,由于在火星比较特殊,该路变成了单向路,且机器人只能出现在这条路的两个端点,问最少需要派多少机器人,才能探清这些矿 解题思路:路可以拼接起来形成一条新的路,所以在所给的条件下还可以再扩展,用floyd将所有能连通的点找出来 接下来就是二分匹配的过程了,求出最大匹配数,在用n-最大匹配数就是答案了 #include<cstdio> #include<cstring> #include<vector> using names