zoukankan      html  css  js  c++  java
  • CodeForces

    Description

    给你一张左边 (n_1) 个点,右边 (n_2) 个点, (m) 条边的二分图。对于每一个 (0le kle minDeg) ,求选取哪些边可以使每个点的度数都不小于 (k)

    (1le n_1,n_2le 2000)(mle 2000)

    Solution

    大力建模谁都会系列,多组询问会炸。

    于是建边就建流量为 (deg[i]-k) 的边,每次增加流量即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    template <class T> inline void read(T &x) {
    	x = 0; static char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar());
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) (x *= 10) += ch - '0';
    }
    
    #define N 5001
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define INF 0x3f3f3f3f
    
    int S, T, head[N], cur[N], tot = 1, q[N], dep[N];
    struct edge { int v, c, next; }e[100001];
    inline void insert(int u, int v, int c) { e[++tot].v = v, e[tot].c = c, e[tot].next = head[u]; head[u] = tot; }
    inline void add(int u, int v, int c) { insert(u, v, c), insert(v, u, 0); }
    inline bool bfs() {
    	memset(dep, 0, sizeof dep); dep[S] = 1;
    	int l = 1, r = 1; q[1] = S;
    	while (l <= r) {
    		int u = q[l++];
    		for (int i = head[u], v; i; i = e[i].next) if (e[i].c && !dep[v = e[i].v]) {
    			dep[v] = dep[u] + 1, q[++r] = v;
    			if (!(v ^ T)) return 1;
    		}
    	}
    	return 0;
    }
    int dfs(int u, int dist) {
    	if (u == T) return dist;
        int ret = 0;
        for (int &i = head[u], v; i; i = e[i].next) if (dep[v = e[i].v] == dep[u] + 1 && e[i].c) {
            int d = dfs(v, min(dist - ret, e[i].c));
            e[i].c -= d, e[i ^ 1].c += d, ret += d;
            if (ret == dist) return dist;
        }
        if (!ret) dep[u] = -1;
        return ret;
    }
    inline void cpy() { rep(i, S, T) cur[i] = head[i]; }
    inline void rec() { rep(i, S, T) head[i] = cur[i]; }
    int dinic() { int ret = 0; cpy(); while (bfs()) ret += dfs(S, INF), rec(); return ret; }
    
    int nu, nv, n, m, deg[N], minDeg = INF;
    vector<int> ans[N];
    struct Data { int u, v; }a[N];
    
    int main() {
    	read(nu), read(nv), read(m), n = nu + nv, T = n + 1;
    	rep(i, 1, m) read(a[i].u), read(a[i].v), a[i].v += nu, deg[a[i].u]++, deg[a[i].v]++;
    	rep(i, 1, n) minDeg = min(minDeg, deg[i]);
    	rep(i, 1, nu) add(S, i, deg[i] - minDeg - 1);
    	rep(i, nu + 1, n) add(i, T, deg[i] - minDeg - 1);
    	int tmp = tot;
    	rep(i, 1, m) add(a[i].u, a[i].v, 1);
    	for (int i = minDeg; i >= 0; i--) {
    		for (int j = 2; j <= tmp; j += 2) e[j].c++;
    		dinic();
    		for (int j = tmp + 1; j <= tot; j += 2) if (e[j].c) ans[i].push_back((j - tmp + 1) / 2);
    	}
    	rep(i, 0, minDeg) {
    		printf("%d ", ans[i].size());
    		for (auto y : ans[i]) printf("%d ", y);
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    多对多关系表的创建方式、forms组件
    SweetAler弹框插件与分页器插件
    Django数据库查询优化与AJAX
    django orm(2)
    Django orm(1)
    Django之视图层与模板层
    Django之路由层
    初识Django之前端后端与数据库的配置
    面试题49
    web框架之初识Django
  • 原文地址:https://www.cnblogs.com/aziint/p/9191660.html
Copyright © 2011-2022 走看看