Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)
题目链接:
题目描述:
在外星上有n个点需要机器人去探险,有m条单向路径。问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过。
解题思路:
一眼看上去是普通的最小边覆盖,但是仔细想后发现如果在原图上进行最大匹配的话,每个点只能经过一次。这样的话对于本题求出的并不是最优解,所以我们要先对原图进行传递闭包处理,然后再进行最大匹配。
这个题目点数太少H_K和匈牙利算法在空间和时间上并没有什么差,就代码复杂度而言匈牙利算法更有优势。
#include <iostream>//匈牙利算法
#include <cstring>
#include <queue>
#include <cmath>
#include <cstdio>
using namespace std; const int maxn = ;
int maps[maxn][maxn], n, m;
int used[maxn], vis[maxn];
void floyd ()
{
for (int k=; k<=n; k++)
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (maps[i][k] && maps[k][j])
maps[i][j] = ;
}
int Find (int u)
{
for (int i=; i<=n; i++)
{
if (!vis[i] && maps[u][i])
{
vis[i] = ;
if (!used[i] || Find(used[i]))
{
used[i] = u;
return ;
}
}
}
return ;
}
int main ()
{
while (scanf ("%d %d", &n, &m), n||m)
{
memset (maps, , sizeof(maps));
while (m --)
{
int u, v;
scanf ("%d %d", &u, &v);
maps[u][v] = ;
}
floyd ();
memset (used, , sizeof(used));
int res = ;
for (int i=; i<=n; i++)
{
memset (vis, , sizeof(vis));
res += Find(i);
}
printf ("%d\n", n - res);
}
return ;
}
#include <iostream>//H_K算法
#include <cstring>
#include <queue>
#include <cmath>
#include <cstdio>
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f;
int maps[maxn][maxn], n, m, dx[maxn], dy[maxn];
int vis[maxn], cx[maxn], cy[maxn], dis;
void floyd ()
{
for (int k=; k<=n; k++)
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (maps[i][k] && maps[k][j])
maps[i][j] = ;
}
bool bfs ()
{
queue <int> Q;
dis = INF;
memset (dx, -, sizeof(dx));
memset (dy, -, sizeof(dy));
for (int i=; i<=n; i++)
if (cx[i] == -)
{
Q.push(i);
dx[i] = ;
}
while (!Q.empty())
{
int u = Q.front();
Q.pop();
if (dx[u] > dis)
break;
for (int i=; i<=n; i++)
{
if (dy[i]==- && maps[u][i])
{
dy[i] = dx[u] + ;
if (cy[i] == -)
dis = dy[i];
else
{
dx[cy[i]] = dy[i] +;
Q.push (cy[i]);
}
}
}
}
return dis != INF;
}
int dfs (int u)
{
for (int v=; v<=n; v++)
{
if (!vis[v] && dx[u]+==dy[v] && maps[u][v])
{
vis[v] = ;
if (cy[v]!=- && dis==dy[v])
continue;
if (cy[v]==- || dfs(cy[v]))
{
cx[u] = v;
cy[v] = u;
return ;
}
}
}
return ;
}
int Max_match ()
{
int res = ;
memset (cx, -, sizeof(cx));
memset (cy, -, sizeof(cy));
while (bfs())
{
memset (vis, , sizeof(vis));
for (int i=; i<=n; i++)
if (cx[i] == -)
res += dfs (i);
}
return res;
}
int main ()
{
while (scanf ("%d %d", &n, &m), n||m)
{
memset (maps, , sizeof(maps));
while (m --)
{
int u, v;
scanf ("%d %d", &u, &v);
maps[u][v] = ;
}
floyd ();
printf ("%d\n", n - Max_match());
}
return ;
}
Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)的更多相关文章
- poj 2594 Treasure Exploration(最小路径覆盖+闭包传递)
http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total ...
- POJ 2594 Treasure Exploration(最小路径覆盖变形)
POJ 2594 Treasure Exploration 题目链接 题意:有向无环图,求最少多少条路径能够覆盖整个图,点能够反复走 思路:和普通的最小路径覆盖不同的是,点能够反复走,那么事实上仅仅要 ...
- POJ 2594 —— Treasure Exploration——————【最小路径覆盖、可重点、floyd传递闭包】
Treasure Exploration Time Limit:6000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64 ...
- poj 2594 Treasure Exploration (二分匹配)
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 6558 Accepted: 2 ...
- POJ 2594 Treasure Exploration 最小可相交路径覆盖
最小路径覆盖 DAG的最小可相交路径覆盖: 算法:先用floyd求出原图的传递闭包,即如果a到b有路径,那么就加边a->b.然后就转化成了最小不相交路径覆盖问题. 这里解释一下floyd的作用如 ...
- poj 2594 Treasure Exploration 二分图匹配
点击打开链接题目链接 Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 7215 ...
- POJ 2594 Treasure Exploration (可相交最小路径覆盖)
题意 给你张无环有向图,问至少多少条路径能够覆盖该图的所有顶点--并且,这些路径可以有交叉. 思路 不是裸的最小路径覆盖,正常的最小路径覆盖中两个人走的路径不能有重复的点,而本题可以重复. 当然我们仍 ...
- POJ 2594 Treasure Exploration (Floyd+最小路径覆盖)
<题目链接> 题目大意: 机器人探索宝藏,有N个点,M条边.问你要几个机器人才能遍历所有的点. 解题分析: 刚开始还以为是最小路径覆盖的模板题,但是后面才知道,本题允许一个点经过多次,这与 ...
- POJ 2594 Treasure Exploration(带交叉路的最小路径覆盖)
题意: 派机器人去火星寻宝,给出一个无环的有向图,机器人可以降落在任何一个点上,再沿着路去其他点探索,我们的任务是计算至少派多少机器人就可以访问到所有的点.有的点可以重复去. 输入数据: 首先是n和 ...
随机推荐
- Java 函数式接口 lambda
import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class Demo1 { ...
- javascript闭包诡异的问题
var funcs = []; for (var i = 0; i < 3; i++) { // let's create 3 functions funcs[i] = function() { ...
- How do I know which version of Javascript I'm using?
Click on this link to see which version your BROWSER is using: http://jsfiddle.net/Ac6CT/ You should ...
- curl -L 跟随跳转
curl -L 跟随跳转 加上-v 就可以看见详细信息: 学习了:https://www.cnblogs.com/davicelee/archive/2011/11/19/cURL.html http ...
- DLL混淆
- [Tools] Create a Chrome Extension
Creating a Chrome extension requires a manifest.json file which defines how your extension will beha ...
- B-Tree 索引和 Hash 索引的对照
对于 B-tree 和 hash 数据结构的理解可以有助于预測不同存储引擎下使用不同索引的查询性能的差异.尤其是那些同意你选择 B-tree 或者 hash 索引的内存存储引擎. B-Tree 索引的 ...
- 从JVM的角度看JAVA代码--代码优化
从JVM的角度看JAVA代码–代码优化 从JVM的角度看JAVA代码代码优化 片段一反复计算 片段二反复比較 在JVM载入优化为class文件,运行class文件时,会有JIT(Just-In-Tim ...
- Linux —— 查找与替换
Linux —— 查找与替换 文本查找: grep, egrep, fgrep grep:根据基本正则表达式定义的模式搜索文档,并将符合模式的文本行显示出来 注意:搜索时属 ...
- 多媒体开发之wis-stream
在live555的mediaServer中,已经实现RTSP-over-HTTP,但默认没有开启.如果要实现这个功能,需要调用RTSPServer::setUpTunnelingOverHTTP(), ...