首页 > 其他分享 >【做题笔记】网络流24题

【做题笔记】网络流24题

时间:2023-08-12 16:57:45浏览次数:36  
标签:24 last int 网络 笔记 read add 配对 define

Part1.飞行员配对方案问题

Problem

有两个集合 \(A\),\(B\)。给定正整数 \(n\),\(m\)。\(A = \{x|1\leq x \leq m\}\),\(B = \{y|m+1\leq y \leq n\}\)。

现在要将 \(A\) 与 \(B\) 集合的元素一一配对,有若干个配对关系,形如“\(u\), \(v\) 可凑一对”。

求有多少个元素能配成一对,并求出方案。

Solve

裸的二分图,但是网络流来写。明明匈牙利可以过,但这是网络流的题,所以用网络流做

配对关系可以转换成连边关系,如果 \(u\) 和 \(v\) 可以配对,就将 \(u \to v\),容量为 \(1\)。

创建两个点,源点 \(s\),汇点 \(t\)。然后将 \(s\) 连向集合 \(A\) 的所有点,集合 \(B\) 的所有点连向 \(t\),容量为 \(1\)。在用此图跑最大流即可。汇点的最大流即为配对的个数。

由于要求方案,要在 \(EK\) 增广的时候记录所配对的点。因为一个增广路上的除去源点和汇点所有点,都会配对。

记得建反边!!

Code

#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
#define inf LLONG_MAX

using namespace std;

inline int read() {
  rint x=0,f=1;char ch=getchar();
  while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
  while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
  return x*f;
}

void print(int x){
  if(x<0){putchar('-');x=-x;}
  if(x>9){print(x/10);putchar(x%10+'0');}
  else putchar(x+'0');
  return;
}

const int N = 1e5 + 10;

struct Node {
  int v, w, nx;
} e[N << 1];

int n, m, s = 0, t = 114, tot = 1, h[N], w[N], ansn, last[N], ans[N];

void add(int u, int v, int w) {
  e[++tot].v = v;
  e[tot].w = w;
  e[tot].nx = h[u];
  h[u] = tot;
}

int bfs() {
  memset(last, -1, sizeof last);
  queue<int> q;
  q.push(s);
  w[s] = inf;
  while(!q.empty()) {
    int x = q.front();
    q.pop();
    if(x == t) break;
    for (int i = h[x]; i; i = e[i].nx) {
      int y = e[i].v, w_ = e[i].w;
      if(w_ > 0 && last[y] == -1) {
        w[y] = min(w[x], w_);
        last[y] = i;
        q.push(y);
      }
    }
  } 
  return last[t] != -1;
}

int EK() {
  int res = 0;
  while(bfs()) {
    res += w[t];
    for (int i = t; i != s; i = e[last[i] ^ 1].v) {
      ans[e[last[i] ^ 1].v] = i;
      e[last[i]].w -= w[t];
      e[last[i] ^ 1].w += w[t]; 
    } 
  }
  return res;
}

signed main() {
  m = read(), n = read();
  For(i,1,m) add(s, i, 1), add(i, s, 0);
  For(i,m+1,n) add(i, t, 1), add(t, i, 0);
  while(1) {
    int u = read(), v = read();
    if(u == -1 && v == -1) break;
    add(u, v, 1);
    add(v, u, 0);
  }
  ansn = EK();
  cout << ansn << '\n';
  For(i,1,m) {
    if(!ans[i] || ans[i] == 114) continue;
    cout << ans[i] << ' ' << i << '\n';
  }
  return 0;
}

标签:24,last,int,网络,笔记,read,add,配对,define
From: https://www.cnblogs.com/Daniel-yao/p/17624964.html

相关文章

  • 正则表达式学习笔记
    .:任意一个字符\d:代表一个数字,等价于[0-9]\D:代表一个非数字,等价于[^\d]或者[^0-9]\s:代表一个空白字符,诸如Space,\n,\r,Tab\S:代表一个非空白字符\w:代表一个单词字符,诸如a,9,_,蛙\W:代表一个非单词字符*:量词,左侧字符串出现任意次(包括\(0\)次)?:量词,左侧字符出现\(\le1\)次+:......
  • 《Rust编程之道》学习笔记一
    《Rust编程之道》学习笔记一序Rust语言的主要特点系统级语言无GC基于LLVM内存安全强类型+静态类型混合编程范式零成本抽象线程安全程序员的快乐何谓快乐?真正的快乐不仅仅是写代码时的“酸爽”,更应该是代码部署到生产环境之后的“安稳”。程序的三大定律程序必须......
  • python复习笔记
    文件操作w=open("c://....","r"或"w"或"a",encoding='utf-8')#字符串后跟b表示二进制文件w.readlines()#读出所有行存入listw.readline()#读出一行,若读完了返回""w.read()#读出所有字符构成字符串w.write("abab")#写入w.close()#关闭impo......
  • 「学习笔记」线段树优化建图
    在建图连边的过程中,我们时常会碰到这种题目,一个点向一段连续的区间中的点连边或者一个连续的区间向一个点连边,如果我们真的一条一条连过去,那一旦点的数量多了复杂度就爆炸了,这里就需要用线段树的区间性质来优化我们的建图了。那棵线段树大概长这个样子。到时候加边的时候是这个......
  • 探索Masscan:全面解析高速网络扫描的神兵利器
    在网络安全领域,高速扫描是一项不可或缺的任务,而Masscan作为一款高性能的网络扫描工具,能够以惊人的速度快速探测大规模网络。本篇博客将深入探讨Masscan的各种参数,逐一介绍其用途、特点和实际应用,帮助你充分了解Masscan并发挥其强大威力。Masscan概览Masscan是一款开源、高速的端口......
  • CentOS7.*基础网络配置
    基础网络配置Ip地址: 唯一表示网络中主机地址的标识,由.隔开的四组十进制数组成每一组数不超过255子网掩码:用来确定IP的网络地址网关:访问其它网段时需要通过的设备IP地址,不同网段通讯需要经过路由器转发出去(网关)Dns服务器:进行域名与ip解析的服务器查看所有网络接口的信息ifconf......
  • 7.7 通俗易懂详解稠密连接网络DenseNet & 手撕稠密连接网络DenseNet
    一.思想与ResNet的区别DenseNet这样拼接有什么好处?DenseNet优点对于每一层,使用前面所有层的特征映射作为输入,并且其自身的特征映射作为所有后续层的输入。DenseNet的优点:缓解了消失梯度问题,加强了特征传播,鼓励特征重用,并大大减少了参数的数量,改进了整个网络的信息流和梯度,这使得......
  • 《CUDA编程:基础与实践》读书笔记(5):统一内存编程
    统一内存(unifiedmemory)是一种逻辑上的概念,它既不是显存、也不是主机内存,而是CPU和GPU都可以访问并能保证一致性的虚拟存储器。使用统一内存对硬件有较高的要求:对于所有功能,GPU架构都必须不低于Kepler架构,主机应用程序必须为64位。对于一些较新的功能,至少需要Pascal架构的GPU......
  • AirNet使用笔记9
    摘要:音视频工具;1、合成通用音视频工具,工具支持将屏幕操作记录文件(.dat/.fdat)和语音回放文件(.wav)合成为通用视频格式文件(例如.mp4).dat是一种自定义的数据格式;.fdat是mp4格式;合并时候需要直接把fdat和wav进行合成(屏幕记录文件(.dat/.fdat)放入工具目录下的datafiles文件夹中;将音频文......
  • Java学习笔记(八)
    6.3 多态6.3.1 多态的概念1、什么是多态?多态:多种形态,多种类型的形式两个角度:(1)一个父类的变量,可以赋值给它各种子类的对象换句话说,一个父类的变量,可以在运行时体现为多种不同的子类对象==>编译时都是父类类型的变量,运行时是各种子类的对象类型(2)一个子类对象,可以赋值给不同......