POJ 2594 Treasure Exploration(最小路径覆盖+Floyd求传递闭包)
来源:互联网 发布:淘宝运营工资高吗 编辑:程序博客网 时间:2024/05/29 15:49
题目链接
题目大意:
一个有向图中, 有若干条连接的路线, 问最少放多少个机器人,可以将整个图上的点都走过。 最小路径覆盖问题。
分析:
这时最小路径覆盖问题, 最小路径覆盖 = |V| - 最大匹配数。 (有关最小路径覆盖,最大匹配问题,相关概念不懂得点这里) 当然做这道题还有一个坑!! 如果有向图的边有相交的情况,那么就不能简单的对原图求二分匹配了 详细讲解看这
最小路径覆盖问题值得注意的地方
首先,最小路径覆盖=总节点数-最大匹配数。这个应该已经是路人皆知了。
所谓最小路径覆盖,是指在一个有向图中,找出最少的几条路径,用它们来覆盖全图
这里说的值得注意的地方,如果有向图的边有相交的情况,那么就不能简单的对原图求二分匹配了
举个例子,假设有图:1->2 2->5 2->3 4->2,事实上,这其实就是两条边:1->5 4->3 ,节点2只是他们的一个交点
如果只是简单的在原图的基础上求二分匹配,那么得到的匹配答案是2,最小路径覆盖答案便是5-2=3。
可是随便一看都能看看出端倪,这个图中,只需要两个点便可以探索完整个地图,这里最小路径覆盖数明显是2。
问题究竟出在哪里呢?其实就和这个交点2有关。既然边有相交,那么他们的连通性也应该连通下去。
解决的办法是对原图进行一次闭包传递(也就是flody),于是便增加了四条边:1->3 1->5 4->3 4->5
这时再求最大匹配数,匹配答案便是3,最小路径覆盖值为2,这是正确答案!
此题跟普通的路径覆盖有点不同。
You should notice that the roads of two different robots may contain some same point.
也就是不同的路径可以有重复点。
先用floyed求闭包,就是把间接相连的点也连起来。
#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>using namespace std;/* **************************************************************************//二分图匹配(匈牙利算法的DFS实现)//初始化:g[][]两边顶点的划分情况//建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配//g没有边相连则初始化为0//uN是匹配左边的顶点数,vN是匹配右边的顶点数//调用:res=hungary();输出最大匹配数//优点:适用于稠密图,DFS找增广路,实现简洁易于理解//时间复杂度:O(VE)//***************************************************************************///顶点编号从0开始的const int MAXN=510;int uN,vN;//u,v数目int g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];bool dfs(int u)//从左边开始找增广路径{ int v; for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改 if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) {//找增广路,反向 linker[v]=u; return true; } } return false;//这个不要忘了,经常忘记这句}int hungary(){ int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res;}//******************************************************************************/void floyed(int n)//求传递闭包{ for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(g[i][j]==0) { for(int k=0;k<n;k++) { if(g[i][k]==1&&g[k][j]==1) { g[i][j]=1; break; } } } }}int main(){ int n,m; int u,v; while(scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; uN=vN=n; memset(g,0,sizeof(g)); while(m--) { scanf("%d%d",&u,&v); u--;v--; g[u][v]=1; } floyed(n); printf("%d\n",n-hungary()); } return 0;}
阅读全文
0 0
- POJ 2594 Treasure Exploration(最小路径覆盖+Floyd求传递闭包)
- poj 2594 Treasure Exploration(可重点最小路径覆盖)(二分匹配+Floyd求传递闭包)
- POJ-2594 Treasure Exploration floyd传递闭包+最小路径覆盖,nice!
- POJ 2594 Treasure Exploration(传递闭包+最小路径覆盖)
- poj 2594 Treasure Exploration最小路径覆盖+传递闭包
- poj 2594 Treasure Exploration 【warshall 求传递闭包 + 最小路径覆盖】
- POJ Treasure Exploration 2594【Warshall求传递闭包+最小路径覆盖】
- POJ-2594-Treasure Exploration-(路径相交的最小路径覆盖+闭包传递)
- POJ 2594 Treasure Exploration(最小路径覆盖-hungary+Floyd)
- POJ 2594 Treasure Exploration (最小路径覆盖+传递闭包(解决可重点))
- POJ 2594 Treasure Exploration (最小路径覆盖+传递闭包(解决可重点))+传递闭包详解
- POJ 2594--Treasure Exploration【二分图 && 最小路径覆盖 && 点可以重复走 && 传递闭包】
- POJ 2594 Treasure Exploration (floyd判断联通+最小路径覆盖)
- poj 2594 Treasure Exploration (最小路径覆盖+Floyd缩点)
- poj 2594 Treasure Exploration(最小路径覆盖(可重点)+floyd)
- POJ 2594 Treasure Exploration 最小路径覆盖
- poj2594Treasure Exploration【最小路径覆盖+floyd传递闭包】
- poj 2594 Treasure Exploration(二分图匹配+Floyd求传递闭包)
- 【树状数组】hdu 4911 Inversion(离散化+树状数组求逆序数)
- svn提交问题--Commit blocked by pre-commit hook(exit code 1)with output:
- 关于正则表达式的“\b”
- LeetCode
- 1874222.html
- POJ 2594 Treasure Exploration(最小路径覆盖+Floyd求传递闭包)
- meavn建立
- Linux截图、查看图片
- 南阳理工ACM 题目21 三个水杯 java代码 广度优先
- 图文详解java内存回收机制
- Jupyter安装r内核
- android与h5之间的互调
- Makefile学习笔记3
- JSON