• JZOJ 3423.Vani和Cl2捉迷藏 & [CTSC2008]祭祀


    ( ext{Problem})

    求一个 (DAG) 的最长反链

    ( ext{Solution})

    (Dilworth) 定理只最长反链等于最小链覆盖
    而原图的链是可相交的,所以我们先做一遍 (Floyd) 传递闭包,使得原图的链不必相交即可覆盖
    这样就转化为最小链覆盖(顶点不可相交)
    于是用网络流经典模型解决

    ( ext{Code})

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N = 405;
    int n, m, h[N], S, T, g[N][N];
    
    struct edge{
    	int to, nxt, w;
    }e[100005];
    inline void add(int u, int v, int w)
    {
    	static int tot = 1;
    	e[++tot] = edge{v, h[u], w}, h[u] = tot;
    }
    
    int Q[N], cur[N], dep[N];
    inline int bfs()
    {
    	for(int i = S; i <= T; i++) cur[i] = h[i], dep[i] = 0;
    	int head = 0, tail = 1;
    	Q[1] = S, dep[S] = 1;
    	while (head < tail)
    	{
    		int now = Q[++head];
    		for(int i = h[now]; i; i = e[i].nxt)
    		{
    			int v = e[i].to;
    			if (dep[v] || !e[i].w) continue;
    			dep[v] = dep[now] + 1, Q[++tail] = v;
    		}
    	}
    	return dep[T];
    }
    int dfs(int x, int mi)
    {
    	if (x == T || mi <= 0) return mi;
    	int flow = 0;
    	for(int i = cur[x]; i; i = e[i].nxt)
    	{
    		cur[x] = i;
    		int v = e[i].to;
    		if (dep[v] ^ (dep[x] + 1) || !e[i].w) continue;
    		int f = dfs(v, min(mi, e[i].w));
    		if (f <= 0) continue;
    		flow += f, mi -= f, e[i].w -= f, e[i ^ 1].w += f;
    		if (mi <= 0) break;
    	}
    	return flow;
    }
    
    int dinic()
    {
    	int res = 0;
    	while (bfs()) res += dfs(S, N);
    	return res;
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1, x, y; i <= m; i++) scanf("%d%d", &x, &y), g[x][y] = 1;
    	for(int k = 1; k <= n; k++)
    		for(int i = 1; i <= n; i++)
    		if (g[i][k])
    			for(int j = 1; j <= n; j++)
    			if (g[k][j]) g[i][j] = 1;
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++)
    			if (g[i][j]) add(i, j + n, 1), add(j + n, i, 0);
    	T = 2 * n + 1;
    	for(int i = 1; i <= n; i++) add(S, i, 1), add(i, S, 0), add(i + n, T, 1), add(T, i + n, 0);
    	printf("%d
    ", n - dinic());
    }
    
  • 相关阅读:
    使用vue-lazyload 加载图片遇到的坑
    nvm 配置安装全局nodejs
    原生 ajax 请求
    angular5 引入第三方插件
    ionic3 组件引用报错问题
    有1到10w这个10w个数,去除2个并打乱次序,如何找出那两个数
    判断数据类型
    统计字符串有多少字节
    php
    数组 、 字符串 简单去重
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15003878.html
Copyright © 2020-2023  润新知