题意:给你一张DAG,让你选取最多的点,使得这些点之间互相不可达。

思路:此问题和最小路径可重复点覆盖等价,先在原图上跑一边传递闭包,然后把每个点拆成两个点i, i + n, 原图中的边(a, b)变成(a, b + n),跑一变网络流, 答案就是n - maxflow;

代码:

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 305;
const int maxm = 100010;
bitset<maxn> b[maxn];
queue<int> q;
int head[maxn], ver[maxm], Next[maxm], edge[maxm], d[maxn];
vector<int> G[maxn];
int n, m, s, t, tot, maxflow;
bool v[maxn];
void dfs(int x) {
if(v[x]) return;
b[x][x] = 1;
for (auto y : G[x]) {
dfs(y);
b[x] |= b[y];
}
v[x] = 1;
return;
}
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
}
bool bfs() {
memset(d, 0, sizeof(d));
while(q.size()) q.pop();
q.push(s);d[s] = 1;
while(q.size()) {
int x= q.front();
q.pop();
for (int i = head[x]; i; i = Next[i]) {
if(edge[i] && !d[ver[i]]) {
q.push(ver[i]);
d[ver[i]] = d[x] + 1;
if(ver[i] == t) return 1;
}
}
}
return 0;
} int dinic(int x, int flow) {
if(x == t) return flow;
int rest = flow, k;
for (int i = head[x]; i && rest; i = Next[i]) {
if(edge[i] && d[ver[i]] == d[x] + 1) {
k = dinic(ver[i], min(rest, edge[i]));
if(!k) d[ver[i]] = 0;
edge[i] -= k;
edge[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
int main() {
int T, x, y;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
tot = 1;
s = n * 2 + 1, t = n * 2 + 2;
for (int i = 1; i <= n; i++)
b[i].reset();
memset(head, 0, sizeof(head));
for (int i = 1; i <= n; i++) {
G[i].clear();
v[i] = 0;
}
maxflow = 0;
for (int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
}
for (int i = 1; i <= n; i++) {
if(!v[i]) {
dfs(i);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(i == j) continue;
if(b[i][j] == 1) {
add(i, j + n, 1);
}
}
}
for (int i = 1; i <= n; i++) {
add(s, i, 1);
add(i + n, t, 1);
}
int flow = 0;
while(bfs())
while(flow = dinic(s, INF)) maxflow += flow;
printf("%d\n", n - maxflow);
}
return 0;
}

  

2017ICPC南宁M The Maximum Unreachable Node Set (偏序集最长反链)的更多相关文章

  1. The Maximum Unreachable Node Set

    题目描述 In this problem, we would like to talk about unreachable sets of a directed acyclic graph G = ( ...

  2. 2017ICPC南宁 M题 The Maximum Unreachable Node Set【二分图】

    题意: 找出不能相互访问的点集的集合的元素数量. 思路: 偏序集最长反链裸题. 代码: #include<iostream> #include<cstring> using n ...

  3. The Maximum Unreachable Node Set 【17南宁区域赛】 【二分匹配】

    题目链接 https://nanti.jisuanke.com/t/19979 题意 给出n个点 m 条边 求选出最大的点数使得这个点集之间 任意两点不可达 题目中给的边是有向边 思路 这道题 实际上 ...

  4. ACM-ICPC 2017 南宁赛区现场赛 M. The Maximum Unreachable Node Set(二分图)

    题目链接:https://nanti.jisuanke.com/t/19979 题意:给出一个 n 个点,m 条边的 DAG,选出最大的子集使得其中结点两两不能到达. 题解:参考自:https://b ...

  5. 2017ICPC南宁赛区网络赛 Minimum Distance in a Star Graph (bfs)

    In this problem, we will define a graph called star graph, and the question is to find the minimum d ...

  6. 2017ICPC南宁赛区网络赛 Overlapping Rectangles(重叠矩阵面积和=离散化模板)

    There are nnn rectangles on the plane. The problem is to find the area of the union of these rectang ...

  7. 2017ICPC南宁赛区网络赛 The Heaviest Non-decreasing Subsequence Problem (最长不下降子序列)

    Let SSS be a sequence of integers s1s_{1}s​1​​, s2s_{2}s​2​​, ........., sns_{n}s​n​​ Each integer i ...

  8. 2017ICPC南宁赛区网络赛 Train Seats Reservation (简单思维)

    You are given a list of train stations, say from the station 111 to the station 100100100. The passe ...

  9. 2017ICPC南宁补题

    https://www.cnblogs.com/2462478392Lee/p/11650548.html https://www.cnblogs.com/2462478392Lee/p/116501 ...

随机推荐

  1. Handling Configuration Changes with Fragments

    This post addresses a common question that is frequently asked on StackOverflow: What is the best wa ...

  2. Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)

    本文转载 https://www.javadoop.com 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.c ...

  3. ThreadLocal在Spring事务管理中的应用

    ThreadLocal是用来处理多线程并发问题的一种解决方案.ThreadLocal是的作用是提供线程的局部变量,在多线程并发环境下,提供了与其他线程隔离的局部变量.通常这样的设计的情况是因为这个局部 ...

  4. Oracle 10046 event

    http://czmmiao.iteye.com/blog/1497509 10046事件概述Oracle的10046事件,可以跟踪应用程序所执行的SQL语句,并且得到其解析次数.执行次数,CPU使用 ...

  5. PJSIP库设置Via地址

    好记性不如烂笔头,解决项目问题,调试代码跟踪到PJSIP 设置Via地址位置,记录下来,以备后用. PJSIP库在方法stateless_send_transport_cb中设置Via地址值,该方法在 ...

  6. ASP.NET Core 上传微信永久视频素材

    话不多说直接上源码 请求实体  public class AddVideoRequest    {        /// <summary>        /// 文件流        / ...

  7. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第1节 Scanner类_1-API概述和使用步骤

    官方翻译的中文版本

  8. 阶段1 语言基础+高级_1-2 -面向对象和封装_15练习使用private关键字定义

    练习使用private关键字定义一个学生类.通过这个联系说明一种特殊情况 先定义了name个age分别再定义getter和setter的方法 boolean类型的getter方法不能叫做get开头的. ...

  9. R语言实现金融数据的时间序列分析及建模

    R语言实现金融数据的时间序列分析及建模 一 移动平均    移动平均能消除数据中的季节变动和不规则变动.若序列中存在周期变动,则通常以周期为移动平均项数.移动平均法可以通过数据显示出数据长期趋势的变动 ...

  10. python+selenium的WebElement对象操作

    webelement对象操作 webelement对象是selenium中所有元素的父类,也就是webelement对象拥有的方法,其它元素对象都会有: 只是不同的对象在调用特定方法时,效果是不一样的 ...