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 (可相交最小路径覆盖)
题意 给你张无环有向图,问至少多少条路径能够覆盖该图的所有顶点--并且,这些路径可以有交叉. 思路 不是裸的最小路径覆盖,正常的最小路径覆盖中两个人走的路径不能有重复的点,而本题可以重复. 当然我们仍 ...
随机推荐
- poj 1442
一个排序的题目. 题意:给你m个数a[m],和n个数b[n]. 首先a[0]….a[b[0]]排序.输出第一个数. 然后a[0]….a[b[1]]排序.输出第二个数. 以此类推,直到输出第n个数. 思 ...
- irssi忽略退出,加入消息
IRSSI: IGNORE JOINS, PARTS, QUITS AND NICKS MESSAGES I use IRC on a daily basis and my client of cho ...
- Java中时间日期格式化
1.与日期时间相关的类: 第一:java.util.Date; 将时间作为一个整体使用.处理时,使用Date类较为简便 第二:j ...
- 16. javacript高级程序设计-HTML5脚本编程
1. HTML5脚本编程 l 跨文档消息传递API能够让我们在不降低同源策略安全性的前提下,在来至不同的域的文档间传递消息 l 原生拖放功能可以方便的指定某个元素是否可以拖动,并在放置时做出响应.还可 ...
- 请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间【转】
本文来自:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之 ...
- NoSQL之【MongoDB】学习(二):DML和查询操作说明
摘要: 操作MongoDB的方法和关系型数据库差别很大,现在对他们进行说明,后期会逐步完善. ##开头表示MySQL** 开头表示MongoDB 创建: Mongodb:文档数据库,擅长存非结构化数据 ...
- C字符串和指针问题汇总
空指针和传参问题 1) 段错误.形参改为二级指针即可 void GetMemory( char *p ){ p = ( ); } void Test( void ){ char *str = NULL ...
- MongoDB 基础 -安全性-(权限操作)
和其他所有数据库一样,权限的管理都差不多一样.mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名.密码和数据库信息.mongodb默认不启用授权认证,只要 ...
- jvm分析
是什么 jps 查看所有的jvm进程,包括进程ID,进程启动的路径等等. jstack 观察jvm中当前所有线程的运行情况和线程当前状态. 系统崩溃了?如果java程序崩溃生成core文件,j ...
- Oracle BFILE备忘
创建目录 create or replace directory exp_dir as '/tmp'; 赋权 grant read, write on directory exp_dir to PUB ...