题目描述

«问题描述:

给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。提示:设V={1,2,.... ,n},构造网络G1=(V1,E1)如下:

每条边的容量均为1。求网络G1的( 0 x , 0 y )最大流。

«编程任务:

对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。

输入输出格式

输入格式:

件第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

输出格式:

从第1 行开始,每行输出一条路径。文件的最后一行是最少路径数。

输入输出样例

输入样例#1:

11 12
1 2
1 3
1 4
2 5
3 6
4 7
5 8
6 9
7 10
8 11
9 11
10 11
输出样例#1:

1 4 7 10 11
2 5 8
3 6 9
3

说明

1<=n<=150,1<=m<=6000

吐槽

  这题洛谷居然没有SPJ,大家来这里交吧。要在洛谷上AC就必须像造数据的人那样——用链式前向星反着加边,然后跑dinic。我的匈牙利明明能得出一个最优解,洛谷就是给我爆零,大坏蛋。下面的代码能出解不能在洛谷AC,大家别想复制了。因为一些事,心情不爽,我也不太想在洛谷上交dinic了,抄了个题解混一波通过数。

解题思路

  裸题。u到v有连边,那么就在二分图里把男u号与女v号牵线,然后跑二分图最大匹配,得到匹配数k,答案最后那行就是$n-k$了。至于前面输出路径,直接顺着二分图走即可,我感觉我的这部分代码挺好懂的(逃)

我的源代码

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n,m;
struct men{
int w;//对象
vector<int> lover;
}man[];
int woman[]={};
inline void add(int u,int v)
{
man[u].lover.push_back(v);
} bool vis[];
bool dfs(int u)
{
int sz=man[u].lover.size();
for(int i=;i<sz;i++)
{
int v=man[u].lover[i];
if(vis[v])continue;
vis[v]=;
if(!woman[v]||dfs(woman[v]))
{
woman[v]=u;
man[u].w=v;
return ;
}
}
return ;
}
void print(int i)
{
if(i==||vis[i])
{
printf("\n");
return;
}
vis[i]=;
printf("%d ",i);
print(man[i].w);
}
int main()
{
scanf("%d%d",&n,&m);
memset(man,,sizeof(man));
for(int i=,u,v;i<=m;i++)
scanf("%d%d",&u,&v),add(u,v);
int ans=;
for(int i=;i<=n;i++) reverse(man[i].lover.begin(),man[i].lover.end());
for(int i=;i<=n;i++)
{
memset(vis,,sizeof(vis));
if(dfs(i))ans++;
}
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
{
if(!vis[i]) print(i);
}
printf("%d\n",n-ans);
return ;
}

洛谷题解代码

#include <stdio.h>
#include <cstring>
#include <queue>
#define maxn 20000
#define fill(x,y) memset(x,y,sizeof(x))
#define min(x,y) x<y?x:y
#define INF 0x7f7f7f7f
using namespace std;
struct edge{int y,w,rev,next;}e[maxn];
int ls[maxn],n,m,maxE=,vis[maxn],state[maxn];
int add(int x,int y,int w)//将边加入
{
e[++maxE]=(edge){y,w,maxE+,ls[x]};
ls[x]=maxE;
e[++maxE]=(edge){x,,maxE-,ls[y]};
ls[y]=maxE;
return ;
}
int bfs(int x)//暴力搜索
{
queue <int> t;
t.push(x);
fill(state,);
state[x]=;
while (!t.empty())
{
int tt=t.front();t.pop();
for (int i=ls[tt];i;i=e[i].next)
{
if (e[i].w>&&state[tt]+<state[e[i].y])
{
state[e[i].y]=state[tt]+;
t.push(e[i].y);
if (e[i].y==n+n+)
return true;
}
}
}
return false;
}
int find(int x,int mn)//dinic
{
if (x==n+n+) return mn;
for (int i=ls[x];i;i=e[i].next)
if (state[x]+==state[e[i].y]&&e[i].w>)
{
int d=find(e[i].y,min(mn,e[i].w));
if (d>)
{
e[i].w-=d;
e[e[i].rev].w+=d;
vis[x]=e[i].y;//记录路径
return d;
}
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y+n,);
}
for (int i=;i<=n;i++)//连边
{
add(,i,);
add(n+i,n+n+,);
}
int ans=; while (bfs())
{
int d=find(,INF);//最大流
ans+=d;
} for (int i=;i<=n;i++)
{
if (vis[i]!=)//输出路径
{
int t=i;
do
{
if (t>n) t-=n;
printf("%d ",t);
int x=vis[t];
vis[t]=;
t=x;
}
while (t!=);
printf("\n");
}
}
printf("%d\n",n-ans);//最小路径覆盖=总点数-最大匹配
return ;
}

洛谷 P2764 LibreOJ 6002 最小路径覆盖问题的更多相关文章

  1. LibreOJ 6002 最小路径覆盖(最大流)

    题解:最小路径覆盖=总点数减去最大匹配数,拆点,按照每条边前一个点连源点,后一个点连汇点跑最大流,即可跑出最大匹配数,然后减一减就可以了~ 代码如下: #include<queue> #i ...

  2. Loj 6002 最小路径覆盖(最大流)

    题意: 求不相交的最小路径覆盖 思路: 连边跑二分图,匹配一条边相当于缩了一条边,答案为n-maxflow 如果是求可以相交的最小路径覆盖的话,先用Floyd跑出可达矩阵,然后所有可达的点连边跑二分图 ...

  3. 【洛谷 P3187】 [HNOI2007]最小矩形覆盖 (二维凸包,旋转卡壳)

    题目链接 嗯,毒瘤题. 首先有一个结论,就是最小矩形一定有条边和凸包重合.脑补一下就好了. 然后枚举凸包的边,用旋转卡壳维护上顶点.左端点.右端点就好了. 上顶点用叉积,叉积越大三角形面积越大,对应的 ...

  4. 洛谷 P2764 最小路径覆盖问题 解题报告

    P2764 最小路径覆盖问题 问题描述: 给定有向图\(G=(V,E)\).设\(P\) 是\(G\) 的一个简单路(顶点不相交)的集合.如果\(V\) 中每个顶点恰好在\(P\) 的一条路上,则称\ ...

  5. 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】

    题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...

  6. 洛谷P2764 最小路径覆盖问题

    有向无环图的最小路径点覆盖 最小路径覆盖就是给定一张DAG,要求用尽量少的不相交的简单路径,覆盖有向无环图的所有顶点. 有定理:顶点数-路径数=被覆盖的边数. 要理解的话可以从两个方向: 假设DAG已 ...

  7. 【刷题】洛谷 P2764 最小路径覆盖问题

    题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...

  8. 洛谷P2764 最小路径覆盖问题(最大流)

    传送门 先说做法:把原图拆成一个二分图,每一个点被拆成$A_i,B_i$,若原图中存在边$(u,v)$,则连边$(A_u,B_v)$,然后$S$对所有$A$连边,所有$B$对$T$连边,然后跑一个最大 ...

  9. AC日记——最小路径覆盖问题 洛谷 P2764

    题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开 ...

随机推荐

  1. multiple web application host under the same website on IIS (authentication mode)

    第一种方式,修改forms的name how to set the forms authentication cookie path assume you have already solved th ...

  2. 【撸码caffe四】 solver.cpp&&sgd_solver.cpp

    caffe中solver的作用就是交替低啊用前向(forward)算法和后向(backward)算法来更新参数,从而最小化loss,实际上就是一种迭代的优化算法. solver.cpp中的Solver ...

  3. codeforces 899F Letters Removing set+树状数组

    F. Letters Removing time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. bzoj 4198 [ Noi 2015 ] 荷马史诗 —— 哈夫曼编码(k叉哈夫曼树)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4198 第一次写哈夫曼树!看了很多博客. 哈夫曼树 & 哈夫曼编码:https://w ...

  5. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

  6. openSTack manual 整合调优

  7. (Go)08.time示例

    package main import ( "fmt" "time" ) func test() { ) } func main() { now := time ...

  8. PCB 工程系统 模拟windows域帐号登入

    一.需求描述: 对于PCB制造企业来说,基本都采用建立共享目享+域名管控权限,好像别的大多数行业都是这样的吧.呵呵 在实际应用中,经常会有这样的问题,自己登入的帐号没有共享目录的权限,但又想通过程序实 ...

  9. epoll实现reactor模式

  10. asp.net限制了上传文件大小为..M,解决方法

    asp.net限制了上传文件大小为4M,在:在web.config里加下面一句,加在<System.web></System.web>之间如下:<system.web&g ...