zoukankan      html  css  js  c++  java
  • BZOJ 2502 清理雪道/ Luogu P4843 清理雪道 (有源汇上下界最小流)

    题意

    有一个有向无环图,求最少的路径条数覆盖所有的边

    分析

    有源汇上下界最小流板题,直接放代码了,不会的看dalao博客:liu_runda
    有点长,讲的很好,静心看一定能看懂

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    template<typename T>inline void read(T &num) {
        char ch; while((ch=getchar())<'0'||ch>'9');
        for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
    }
    
    const int MAXN = 105;
    const int MAXM = 100005;
    const int inf = 1e9;
    int n, deg[MAXN], s, t, ss, tt, S, T;
    int fir[MAXN], info[MAXN], cnt;
    struct edge { int to, nxt, c; }e[MAXM];
    inline void add(int u, int v, int cc) {
    	e[cnt] = (edge){ v, fir[u], cc }; fir[u] = cnt++;
    	e[cnt] = (edge){ u, fir[v], 0 }; fir[v] = cnt++;
    }
    int q[MAXN], vis[MAXN], cur, dis[MAXN];
    inline bool bfs() {
    	int head = 0, tail = 0;
    	vis[S] = ++cur; q[tail++] = S;
    	while(head < tail) {
    		int u = q[head++];
    		for(int i = fir[u]; ~i; i = e[i].nxt)
    			if(e[i].c && vis[e[i].to] != cur)
    				dis[e[i].to] = dis[u] + 1, vis[e[i].to] = cur, q[tail++] = e[i].to;
    	}
    	if(vis[T] == cur) memcpy(info, fir, sizeof fir);
    	return vis[T] == cur;
    }
    int dfs(int u, int Max) {
    	if(u == T) return Max;
    	int flow = 0, delta;
    	for(int &i = info[u]; ~i; i = e[i].nxt)
    		if(e[i].c && dis[e[i].to] == dis[u] + 1 && (delta=dfs(e[i].to, min(Max-flow, e[i].c)))) {
    			e[i].c -= delta, e[i^1].c += delta, flow += delta;
    			if(flow == Max) return flow;
    		}
    	return flow;
    }
    inline int dinic() {
    	int flow = 0, x;
    	while(bfs()) {
    		while((x=dfs(S, inf)))
    			flow += x;
    	}
    	return flow;
    }
    inline void del(int u) {
    	for(int i = fir[u]; ~i; i = e[i].nxt) e[i].c = e[i^1].c = 0;
    }
    int main ()
    {
    	memset(fir, -1, sizeof fir);
        read(n);
    	for(int i = 1, j, tot; i <= n; ++i) {
    		read(tot);
    		while(tot--) read(j), --deg[i], ++deg[j], add(i, j, inf-1);
    	}
    	s = n+1, t = n+2, ss = n+3, tt = n+4;
    	for(int i = 1; i <= n; ++i)
    		add(s, i, inf), add(i, t, inf);
    	for(int i = 1; i <= n; ++i)
    		if(deg[i] < 0) add(i, tt, -deg[i]);
    		else if(deg[i] > 0) add(ss, i, deg[i]);
    	add(t, s, inf);
    	S = ss, T = tt;
    	dinic();
    	int flow0 = e[cnt-1].c;
    	e[cnt-1].c = e[cnt-2].c = 0;
    	del(ss); del(tt);
    	S = t, T = s;
    	printf("%d
    ", flow0-dinic());
    }
    

    Upd:Upd:开始把"flow0dinic()flow0-dinic()“写成了”flow0+dinic()flow0+dinic()",洛谷上居然80pts80pts,数据有点水啊

  • 相关阅读:
    Eclipse安装Git插件及简单操作
    物联网架构成长之路(28)-Docker练习之MQ中间件(Kafka)
    版本分支管理标准
    社交的基本逻辑
    委托投资方案
    印钞机 V1.0(量化选基总结)
    中小研发团队架构实践之总体架构设计
    FOF 全面科普贴(转载)
    DUIR Framework 相关技术介绍
    使用融资的心得和教训
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039421.html
Copyright © 2011-2022 走看看