zoukankan      html  css  js  c++  java
  • 校内模拟赛 Attack's Fond Of LeTri

    Attack's Fond Of LeTri

    题意:

      n个房子m条路径边的无向图,每个房子可以最终容纳b个人,初始有a个人,中途超过可以超过b个人,每条边有一个长度,经过一条边的时间花费为边的长度。求所有人都进入房子的最小时间。如果不能容纳所有人,输出最少多少人无法进入房子。

    分析:

      注意图不一定联通!!!

      首先Floyd一遍,求出任意两点之间的距离,二分一个答案,然后拆点建二分图,S想每个点连a的容量,另一个点向T连b的容量,对于两个点a,b,如果dis[a][b]<=二分的这个数,就加入一条左边到右边的边,容量为inf。满流即可。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #define fore(i, u, v) for (int i = head[u], v = e[i].to; i; i = e[i].nxt, v = e[i].to) 
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    const int N = 5005, INF = 1e9;
    struct Edge { int to, nxt, cap; } e[100005];
    int head[N], q[50005], a[N], b[N], dis[N], cur[N];
    int En = 1, S, T, n;
    LL d[305][305], Sum;
    
    inline void add_edge(int u,int v,int f) {
        ++En; e[En].to = v, e[En].nxt = head[u], e[En].cap = f; head[u] = En;
        ++En; e[En].to = u, e[En].nxt = head[v], e[En].cap = 0; head[v] = En;
    }
    bool bfs() {
        for (int i = 0; i <= T; ++i) dis[i] = -1, cur[i] = head[i];
        int L = 1, R = 0; q[++R] = S; dis[S] = 0;
        while (L <= R) {
            int u = q[L ++];
            fore(i, u, v) 
                if (dis[v] == -1 && e[i].cap > 0) {
                    dis[v] = dis[u] + 1;
                    if (v == T) return true;
                    q[++R] = v;
                }
        }
        return false;
    }
    int dfs(int u,int flow) {
        if (u == T) return flow;
        int used = 0, tmp;
        for (int &i = cur[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (dis[v] == dis[u] + 1 && e[i].cap > 0) {
                tmp = dfs(v, min(e[i].cap, flow - used));
                if (tmp > 0) {
                    e[i].cap -= tmp, e[i ^ 1].cap += tmp; used += tmp;
                    if (used == flow) break;
                }
            }
        }
        if (flow != used) dis[u] = -1;
        return used;
    }
    bool dinic(LL x, bool flag) {
        S = 0, T = n + n + 1, En = 1;
        memset(head, 0, sizeof(head));
        for (int i = 1; i <= n; ++i) add_edge(S, i, a[i]), add_edge(i + n, T, b[i]);
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= n; ++j) 
                if (d[i][j] <= x) add_edge(i, j + n, INF);
        LL ans = 0;
        while (bfs()) ans += dfs(S, INF);
        if (flag && ans != Sum) {
            cout << "NO
    " << Sum - ans; exit(0);
        }
        return ans == Sum;
    }
    void solve(int m) {
        for (int i = 1; i <= n; ++i) Sum += a[i];
    //    memset(d, 0x3f, sizeof(d));
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= n; ++j) d[i][j] = 1e18;
        for (int i = 1; i <= n; ++i) d[i][i] = 0;
        for (int i = 1; i <= m; ++i) {
            int u = read(), v = read(), w = read(); 
            d[u][v] = min(d[u][v], (LL)w);
            d[v][u] = min(d[v][u], (LL)w);
        }
        for (int k = 1; k <= n; ++k) 
            for (int i = 1; i <= n; ++i) 
                for (int j = 1; j <= n; ++j) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        LL L = 1e18, R = 0, ans = 0;
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= n; ++j) if (d[i][j] != 1e18) L = min(L, d[i][j]), R = max(R, d[i][j]); // 注意要有dis[i][j]!=1e18???
        dinic(R, 1);
        while (L <= R) {
            LL mid = (L + R) >> 1;
            if (dinic(mid, 0)) R = mid - 1, ans = mid;
            else L = mid + 1;
        }
        cout << "YES
    " << ans << "
    ";
    }
    int main() {
        n = read();int m = read(); 
        for (int i = 1; i <= n; ++i) a[i] = read(), b[i] = read();
        solve(m);
        return 0;
    }
  • 相关阅读:
    盘古越狱工具在用户空间的行为
    hdu 5538 House Building(长春现场赛——水题)
    html 锚点定位
    OOP版电子词典
    有趣的JavaScript原生数组函数
    &lt;LeetCode OJ&gt; 121. /122. Best Time to Buy and Sell Stock(I / II)
    hadoop 出现FATAL conf.Configuration: error parsing conf file,异常
    IT痴汉的工作现状10-Sprint Planning
    2015 Astar Contest
    无法使用BIPublisher开发报表
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10651121.html
Copyright © 2011-2022 走看看