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. ASP.NET Core中配置监听URLs的五种方式

    原文: 5 ways to set the URLs for an ASP.NET Core app 作者: Andrew Lock 译者: Lamond Lu 默认情况下,ASP. NET Core ...

  2. delphi使用ADO在sql数据库存取图片的方法

    我一直不认为能把代码写的和天书一样的程序员是好的程序员,那不过是因为我真的对delphi也就是略懂皮毛,太深了看不懂.网上查询数据库存取图片的方式,看的是一头雾水,有人提出保存路径使用时再调用,方法很 ...

  3. stand up meeting 12/3/2015

    part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 初始化弹窗的弹出位置并捕捉弹窗区域内的鼠标控制事件,初步解决弹窗的拖拽功能:    6 UWP对控件的支持各种看不懂,属性 ...

  4. F - Make It Equal CodeForces - 1065C

    题目大意:有n座塔,塔高h[i],每次给定高度H对他们进行削切,要求每次削掉的所有格子数不能超过k个,输出最少削几次才能使所有塔的高度相同. 思路一:差分+贪心 对于每一个高度h,用一个数组让1~h的 ...

  5. 数据挖掘入门系列教程(十点五)之DNN介绍及公式推导

    深度神经网络(DNN,Deep Neural Networks)简介 首先让我们先回想起在之前博客(数据挖掘入门系列教程(七点五)之神经网络介绍)中介绍的神经网络:为了解决M-P模型中无法处理XOR等 ...

  6. Python之numpy,pandas实践

    Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言. Jupyter Notebook 的本质是一个 Web 应用程序,便 ...

  7. 【认证与授权】Spring Security的授权流程

    上一篇我们简单的分析了一下认证流程,通过程序的启动加载了各类的配置信息.接下来我们一起来看一下授权流程,争取完成和前面简单的web基于sessin的认证方式一致.由于在授权过程中,我们预先会给用于设置 ...

  8. php二维数组的排序

    /**  * @desc arraySort php二维数组排序 按照指定的key 对数组进行排序  * @param array $arr 将要排序的数组  * @param string $key ...

  9. [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码生成 (修订版)

    [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码生成 (修订版) 目录 [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码 ...

  10. sql注入学习笔记

    1.什么是SQL注入 SQL注入就是指web应用程序对用户输入的数据的合法性没有判断,前端传入后端的参数带有数据库查询的语句,攻击者可以构造不同的SQL语句来实现对数据库的操作. 2.SQL注入原理 ...