P2764 最小路径覆盖问题

这个题目之前第一次做的时候感觉很难,现在好多了,主要是二分图定理不太记得了,二分图定理

知道这个之后就很好写了,首先我们对每一个点进行拆点,拆完点之后就是跑最大流,求出最大匹配数,

然后就可以求出最小路径覆盖数,这个题目的难点在于求路径,其实很好写,就是用一个数组来写就可以了。

每一个点都记录一下它下一个点是哪个位置,最后把拆开了的点合并就可以了。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <string>
#include <iostream>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 3e5 + ;
typedef long long ll;
struct edge {
int u, v, c, f;
edge(int u, int v, int c, int f) :u(u), v(v), c(c), f(f) {}
};
vector<edge>e;
vector<int>G[maxn];
int level[maxn];//BFS分层,表示每个点的层数
int iter[maxn];//当前弧优化
int m;
bool tag[maxn];
int to[maxn];
void init(int n) {
for (int i = ; i <= n; i++)G[i].clear();
e.clear();
}
void addedge(int u, int v, int c) {
e.push_back(edge(u, v, c, ));
e.push_back(edge(v, u, , ));
m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
void BFS(int s)//预处理出level数组
//直接BFS到每个点
{
memset(level, -, sizeof(level));
queue<int>q;
level[s] = ;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v = ; v < G[u].size(); v++) {
edge& now = e[G[u][v]];
if (now.c > now.f && level[now.v] < ) {
level[now.v] = level[u] + ;
q.push(now.v);
}
}
}
}
int dfs(int u, int t, int f)//DFS寻找增广路
{
if (u == t)return f;//已经到达源点,返回流量f
for (int &v = iter[u]; v < G[u].size(); v++)
//这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
//在每次找增广路的时候,数组要清空
{
edge &now = e[G[u][v]];
if (now.c - now.f > && level[u] < level[now.v])
//now.c - now.f > 0表示这条路还未满
//level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
{
int d = dfs(now.v, t, min(f, now.c - now.f));
if (d > ) {
to[now.u] = now.v;
tag[now.v] = ;
now.f += d;//正向边流量加d
e[G[u][v] ^ ].f -= d;
//反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
return d;
}
}
}
return ;
}
int Maxflow(int s, int t) {
int flow = ;
for (;;) {
BFS(s);
if (level[t] < )return flow;//残余网络中到达不了t,增广路不存在
memset(iter, , sizeof(iter));//清空当前弧数组
int f;//记录增广路的可增加的流量
while ((f = dfs(s, t, inf)) > ) {
flow += f;
}
}
return flow;
} int main()
{
int n, m;
scanf("%d%d", &n, &m);
int s = , t = n + n + ;
for(int i=;i<=m;i++)
{
int x, y;
scanf("%d%d", &x, &y);
addedge(x, y + n, );
}
for(int i=;i<=n;i++)
{
addedge(s, i, );
addedge(i + n, t, );
}
memset(to, -, sizeof(to));
memset(tag, , sizeof(tag));
int ans = Maxflow(s, t);
ans = n - ans;
for(int i=;i<=n;i++)
{
if (tag[i + n]) continue;
int x = i;
while()
{
printf("%d ", x);
if (to[x] == -) break;
x = to[x] - n;
}
printf("\n");
}
printf("%d\n", ans);
return ;
}

P2764 最小路径覆盖问题 网络流重温的更多相关文章

  1. P2764 最小路径覆盖问题(网络流24题之一)

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

  2. 洛谷-p2764(最小路径覆盖)(网络流24题)

    #include<iostream> #include<algorithm> #include<queue> #include<cstring> #in ...

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

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

  4. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  5. Luogu P2764 最小路径覆盖问题(二分图匹配)

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

  6. 网络流二十四题之P2764 最小路径覆盖问题

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

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

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

  8. luogu P2764 最小路径覆盖问题

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

  9. P2764 最小路径覆盖问题

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

随机推荐

  1. webWMS开发过程记录(一)- 软件开发的流程

    前言:计划开发一个webWMS,并将开发过程比较完整的记录下来.希望可以完成这个目标 软件开发的流程: 1. 了解该项目的相关概念. 了解所要开发的软件属于什么产品.该产品的基本定义是什么?基本功能模 ...

  2. 选择IT行业的自我心得,希望能帮助到各位!(四)

    俗话说,只有尝过人生的苦,吃过人生的亏,你才能吃一见长一智,人生教会了我们该如何去吃亏,该如何做人,该如何和人打交道,生活会让我们低下无数的头,就看你怎么去面对这些曲折该如何告诉自己不能就被这样打到, ...

  3. F - Robot Motion 栈加BFS

    A robot has been programmed to follow the instructions in its path. Instructions for the next direct ...

  4. SpringCloud-Ribbon负载均衡机制、手写轮询算法

    Ribbon 内置的负载均衡规则 在 com.netflix.loadbalancer 包下有一个接口 IRule,它可以根据特定的算法从服务列表中选取一个要访问的服务,默认使用的是「轮询机制」 Ro ...

  5. 本地同时使用多个git账号

    config文件说明 Git Document指示在首次安装git的时候需要配置Config的相关内容信息,有三个地方存储了config文件,决定了读取的场景不同. 1 /etc/gitconfig: ...

  6. SUCTF 2019 Upload labs 2 踩坑记录

    SUCTF 2019 Upload labs 2 踩坑记录 题目地址 : https://github.com/team-su/SUCTF-2019/tree/master/Web/Upload La ...

  7. jmeter5.1.1 生成html报告

    1.首先需要准备好 .jmx 脚本 2.修改jmeter.properties文件(把注解去掉,报告中才能展示所需信息) jmeter.save.saveservice.output_format=x ...

  8. DataTable 与XML 交互

    一.将DataTable的内容写入到XML文件中 /// <summary> /// 将DataTable的内容写入到XML文件中 /// </summary> /// < ...

  9. Youtube推荐算法的前世今生

    第一阶段,基于User-Video图游历算法,2008年[1]. 在这个阶段,YouTube认为应该给用户推荐曾经观看过视频的同类视频,或者说拥有同一标签的视频.然而此时,YouTube的视频已是数千 ...

  10. 数值分析实验之曲线最小二乘拟合含有噪声扰动(python实现)

    一.实验目的 掌握最小二乘法拟合离散数据,多项式函数形式拟合曲线以及可以其他可以通过变量变换转化为多项式的拟合曲线目前待实现功能: 1. 最小二乘法的基本实现. 2. 用不同数据量,不同参数,不同的多 ...