POJ 2594 Treasure Exploration (可相交最小路径覆盖)

时间:2022-08-23 22:19:50

题意

给你张无环有向图,问至少多少条路径能够覆盖该图的所有顶点——并且,这些路径可以有交叉。

思路

不是裸的最小路径覆盖,正常的最小路径覆盖中两个人走的路径不能有重复的点,而本题可以重复。

当然我们仍可将问题转化为最小路径覆盖。如果一个人需要经过另一个人走过的点的时候,让他直接从该点上空飞过去,越过该点,直接走下一个点。如果我们赋予每个人这种能力,那么求得的无重复点的最小路径覆盖结果,就是题目要求的结果,因为需要重复的地方只要飞过去,就可以不重复了。赋予这个能力的方法就是预处理用Floyd求传递闭包把所有点能间接到达的点全都改为直接到达。然后正常求最小路径覆盖即可。

代码

[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m) for (int i = begin; i < begin+m; i ++)
using namespace std;
const int MAXV = 1005; //|V1|+|V2|
struct MaximumMatchingOfBipartiteGraph{
int vn;
vector <int> adj[MAXV];
void init(int n){ //二分图两点集点的个数
vn = n;
for (int i = 0; i <= vn; i ++) adj[i].clear();
}
void add_uedge(int u, int v){
adj[u].push_back(v);
adj[v].push_back(u);
}
bool vis[MAXV];
int mat[MAXV]; //记录已匹配点的对应点
bool cross_path(int u){
for (int i = 0; i < (int)adj[u].size(); i ++){
int v = adj[u][i];
if (!vis[v]){
vis[v] = true;
if (mat[v] == 0 || cross_path(mat[v])){
mat[v] = u;
mat[u] = v;
return true;
}
}
}
return false;
}
int hungary(){
MEM(mat, 0);
int match_num = 0;
for (int i = 1; i <= vn; i ++){
MEM(vis, 0);
if (!mat[i] && cross_path(i)){
match_num ++;
}
}
return match_num;
}
void print_edge(){
for (int i = 1; i <= vn; i ++){
for (int j = 0; j < (int)adj[i].size(); j ++){
printf("u = %d v = %d\n", i, adj[i][j]);
}
}
}
}match;
bool reach[MAXV>>1][MAXV>>1];
void floyd(int n){
REP(k, 1, n) REP(i, 1, n) REP(j, 1, n){
if (reach[i][j]) continue;
reach[i][j] = reach[i][k] && reach[k][j];
}
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int n, m;
while(scanf("%d %d", &n, &m), n+m){
if (0 == m){
printf("%d\n", n);
continue;
}
MEM(reach, false);
REP(i, 0, m){
int u, v;
scanf("%d %d", &u, &v);
reach[u][v] = true;
}
floyd(n);
match.init(n);
REP(i, 1, n)
REP(j, 1, n){
if (reach[i][j])
match.add_uedge(i, j+n);
}
printf("%d\n", n-match.hungary());
}
return 0;
}
[/cpp]

POJ 2594 Treasure Exploration (可相交最小路径覆盖)的更多相关文章

  1. POJ2594:Treasure Exploration(Floyd &plus; 最小路径覆盖)

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 9794   Accepted: 3 ...

  2. POJ-2594 Treasure Exploration,floyd&plus;最小路径覆盖!

                                                 Treasure Exploration 复见此题,时隔久远,已忘,悲矣! 题意:用最少的机器人沿单向边走完( ...

  3. POJ-2594 Treasure Exploration floyd传递闭包&plus;最小路径覆盖,nice!

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8130   Accepted: 3 ...

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

    POJ 2594 Treasure Exploration 题目链接 题意:有向无环图,求最少多少条路径能够覆盖整个图,点能够反复走 思路:和普通的最小路径覆盖不同的是,点能够反复走,那么事实上仅仅要 ...

  5. Poj 2594 Treasure Exploration &lpar;最小边覆盖&plus;传递闭包&rpar;

    题目链接: Poj 2594 Treasure Exploration 题目描述: 在外星上有n个点需要机器人去探险,有m条单向路径.问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过 ...

  6. poj 2594 Treasure Exploration &lpar;二分匹配&rpar;

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 6558   Accepted: 2 ...

  7. poj 2594 Treasure Exploration&lpar;最小路径覆盖&plus;闭包传递&rpar;

    http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total ...

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

    Treasure Exploration Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64 ...

  9. POJ 2594 Treasure Exploration 最小可相交路径覆盖

    最小路径覆盖 DAG的最小可相交路径覆盖: 算法:先用floyd求出原图的传递闭包,即如果a到b有路径,那么就加边a->b.然后就转化成了最小不相交路径覆盖问题. 这里解释一下floyd的作用如 ...

随机推荐

  1. 【转】Linux常用命令大全

    原文地址:http://www.php100.com/html/webkaifa/Linux/2009/1106/3485.html 系统信息 arch 显示机器的处理器架构(1) uname -m ...

  2. Andorid手机振动器&lpar;Vibrator&rpar;的使用

    标签: android vibrator 震动器 it 分类: Andorid 获取振动器Vibrator实例: Vibrator  mVibrator = (Vibrator) context.ge ...

  3. MyEclipse server窗口 Could not create the view&colon; An unexpected exception was thrown 错误解决

    MyEclipse 打开后有时候莫名的在server窗口里抛出“Could not create the view: An unexpected exception was thrown”错误,解决办 ...

  4. 看日记学git摘要~灰常用心的教程

    看日记学git linux 命令行 cd ls / ls -a clear mkdir rmdir echo "hi, good day" > hi.txt touch he ...

  5. 画图必备numpy函数

    给定一堆数字,需要统计这些数字中每个数字的个数. 如果这些数字是整数,那自然可以精确统计出来. 如果这些数字是浮点数,如果精确统计会发现几乎每个数字都只出现了一次.所以浮点数就要通过区间的方式进行统计 ...

  6. spring注解第07课 &commat;Valid和&commat;Validated的总结区分

    @Valid: @Valid注解用于校验,所属包为:javax.validation.Valid. ① 首先需要在实体类的相应字段上添加用于充当校验条件的注解,如:@Min,如下代码(age属于Gir ...

  7. gdb 拾遗

    1,跳过某个特定信号 (gdb) handle SIGPIPE nostop noprint pass 2,break在特定的系统调用处 (gdb) catch syscall 3 3,遇到一个断点的 ...

  8. 创建自己的共用js库

    直至昨晚为止,学习了一个多月的MVC与jQuery,从所做的练习中,发觉jQuery的代码也有跟C#语言一样可以重构,多页面有相同使用的方法函数,均可以放置于一个单独立的js文件或是自定义的js库中. ...

  9. 8 -- 深入使用Spring -- 3&period;&period;&period;1 Resource实现类

    8.3.1 Resource实现类 Resource接口是Spring资源访问的接口,具体的资源访问由该接口的实现类完成. Spring提供的Resource接口的实现类: ⊙ UrlResource ...

  10. MySQL在linux上的source code安装方法&lpar;configure&rpar;

    1.建立操作系统用户和组 [root@faspdev ~]# groupadd mysql [root@faspdev ~]# useradd -g mysql mysql 2.解压安装文件,进入解压 ...