loj 1429(可相交的最小路径覆盖)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1429
思路:这道题还是比较麻烦的,对于求有向图的可相交的最小路径覆盖,首先要解决成环问题,可以先染色缩点重建图,然后就是如何来处理这个路径可以相交这个问题,这里可以用bfs求出任意两点之间是否可达,如果可达,就连边,然后就是HK算法求最大匹配了,最小路径覆盖 = 顶点数 - 最大匹配。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
using namespace std; const int MAXN = ( + );
const int MAXM = ( + );
int n, m;
int cnt, scc_count;
bool Instack[MAXN];
int low[MAXN], dfn[MAXN], color[MAXN];
vector<int > g[MAXN];
stack<int > S; void Tarjan(int u)
{
low[u] = dfn[u] = ++cnt;
Instack[u] = true;
S.push(u);
for (int i = ; i < (int)g[u].size(); i++) {
int v = g[u][i];
if (dfn[v] == ) {
Tarjan(v);
low[u] = min(low[u], low[v]);
} else if (Instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
scc_count++;
int v;
do {
v = S.top();
S.pop();
Instack[v] = false;
color[v] = scc_count;
} while (u != v);
}
} bool Isok[MAXN][MAXN];
bool mark[MAXN];
vector<int > reg[MAXN]; void bfs(int st)
{
memset(mark, false, sizeof(mark));
queue<int >que;
que.push(st);
mark[st] = true;
while (!que.empty()) {
int u = que.front();
que.pop();
for (int i = ; i < (int)reg[u].size(); i++) {
int v = reg[u][i];
if (!mark[v]) {
mark[v] = true;
que.push(v);
}
}
}
} void Build()
{
for (int i = ; i <= scc_count; i++) {
reg[i].clear();
}
for (int i = ; i <= scc_count; i++) {
for (int j = ; j <= scc_count; j++) {
if (i != j && Isok[i][j]) {
reg[i].push_back(j);
}
}
}
} int lx[MAXN], ly[MAXN];
int distx[MAXN], disty[MAXN]; bool MaxMatch_bfs()
{
bool flag = false;
memset(distx, , sizeof(distx));
memset(disty, , sizeof(disty));
queue<int > que;
for (int i = ; i <= scc_count; i++) {
if (lx[i] == -) que.push(i);
}
while (!que.empty()) {
int u = que.front();
que.pop();
for (int i = ; i < (int)reg[u].size(); i++) {
int v = reg[u][i];
if (disty[v] == ) {
disty[v] = distx[u] + ;
if (ly[v] == -) flag = true;
else {
distx[ly[v]] = disty[v] + ;
que.push(ly[v]);
}
}
}
}
return flag;
} int dfs(int u)
{
for (int i = ; i < (int)reg[u].size(); i++) {
int v = reg[u][i];
if (disty[v] == distx[u] + ) {
disty[v] = ;
if (ly[v] == - || dfs(ly[v])) {
ly[v] = u;
lx[u] = v;
return ;
}
}
}
return ;
} int MaxMatch()
{
memset(lx, -, sizeof(lx));
memset(ly, -, sizeof(ly));
int res = ;
while (MaxMatch_bfs()) {
for (int i = ; i <= scc_count; i++) {
if (lx[i] == -) res += dfs(i);
}
}
return res;
} int main()
{
int _case, t = ;
scanf("%d", &_case);
while (_case--) {
scanf("%d %d", &n, &m);
for (int i = ; i <= n; i++) {
g[i].clear();
reg[i].clear();
}
while (m--) {
int u, v;
scanf("%d %d", &u, &v);
g[u].push_back(v);
}
//强联通缩点重建图
cnt = scc_count = ;
memset(dfn, , sizeof(dfn));
for (int i = ; i <= n; i++) {
if (dfn[i] == ) Tarjan(i);
}
for (int u = ; u <= n; u++) {
for (int i = ; i < (int)g[u].size(); i++) {
int v = g[u][i];
if (color[u] != color[v]) {
reg[color[u]].push_back(color[v]);
}
}
}
//bfs求出新图中的任意两点之间是否可达
memset(Isok, false, sizeof(Isok));
for (int i = ; i <= scc_count; i++) {
bfs(i);
for (int j = ; j <= scc_count; j++) {
if (mark[j]) {
Isok[i][j] = true;
}
}
}
//对于那些可达的点重新连边
Build();
//bfs求解最大匹配;
//最小路径覆盖 = 顶点数 - 最大匹配数
int ans = MaxMatch();
printf("Case %d: %d\n", t++, scc_count- ans);
}
return ;
}
loj 1429(可相交的最小路径覆盖)的更多相关文章
- POJ2594 Treasure Exploration【DAG有向图可相交的最小路径覆盖】
题目链接:http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K T ...
- poj 2594(可相交的最小路径覆盖)
题目链接:http://poj.org/problem?id=2594 思路:本来求最小路径覆盖是不能相交的,那么对于那些本来就可达的点怎么处理,我们可以求一次传递闭包,相当于是加边,这样我们就可以来 ...
- Treasure Exploration POJ - 2594 【有向图路径可相交的最小路径覆盖】模板题
Have you ever read any book about treasure exploration? Have you ever see any film about treasure ex ...
- poj 2594Treasure Exploration(有向图路径可相交的最小路径覆盖)
1 #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- Loj 6002 最小路径覆盖(最大流)
题意: 求不相交的最小路径覆盖 思路: 连边跑二分图,匹配一条边相当于缩了一条边,答案为n-maxflow 如果是求可以相交的最小路径覆盖的话,先用Floyd跑出可达矩阵,然后所有可达的点连边跑二分图 ...
- Light OJ 1429 Assassin`s Creed (II) BFS+缩点+最小路径覆盖
题目来源:Light OJ 1429 Assassin`s Creed (II) 题意:最少几个人走全然图 能够反复走 有向图 思路:假设是DAG图而且每一个点不能反复走 那么就是裸的最小路径覆盖 如 ...
- [LOJ#6002]「网络流 24 题」最小路径覆盖
[LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是 ...
- POJ 2594 Treasure Exploration (可相交最小路径覆盖)
题意 给你张无环有向图,问至少多少条路径能够覆盖该图的所有顶点--并且,这些路径可以有交叉. 思路 不是裸的最小路径覆盖,正常的最小路径覆盖中两个人走的路径不能有重复的点,而本题可以重复. 当然我们仍 ...
随机推荐
- hibernate xx(tableName) is not mapped
数据库中表名是:book,数据库表名不区分大小写的 之后我在hibernate 使用book, String sql="from book"; Query query=sessio ...
- FFmpeg-20160413-snapshot-bin
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 F ...
- iOS9 UI Tests探索笔记
UI Tests是什么? UI Tests是一个自动测试UI与交互的Testing组件 UI Tests有什么用? 它可以通过编写代码.或者是记录开发者的操作过程并代码化,来实现自动点击某个按钮.视图 ...
- Greedy:Graveyard Design(POJ 2100)
墓地 题目大意,给定一个整数,要你找出他的平方和组合 太简单了....不过一开始我储存平方和想降低时间,后来发现会超内存,直接用时间换空间了,游标卡尺法 #include <iostream&g ...
- iOS runtime 的经典作用
- September 2nd 2016 Week 36th Friday
How does the world look through your eyes? 你眼里的世界是什么样子的? How does the world look through your eyes? ...
- August 26th 2016 Week 35th Friday
It always seems impossible until it's done. 在事情未完成之前,一切都看似不可能. When I was young, once I had to lift ...
- tomcat和apache区别联系
tomcat和apache区别联系 Apache是普通服务器,本身只支持html即普通网页.不过可以通过插件支持php,还可以与Tomcat连通(单向Apache连接Tomcat, 就是说通过Apac ...
- Android下拉刷新效果实现
本文主要包括以下内容 自定义实现pulltorefreshView 使用google官方SwipeRefreshLayout 下拉刷新大致原理 判断当前是否在最上面而且是向下滑的,如果是的话,则加载数 ...
- 菜鸟学Linux命令:端口查看和操作命令
>>端口和进程 端口不是独立存在的,它是依附于进程的.某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了.下次若某个进程再次开启,则相应的端口也再次开启. >> ...