zoukankan      html  css  js  c++  java
  • HDU 3987 Harry Potter and the Forbidden Forest(边权放大法+最小割)

    Harry Potter and the Forbidden Forest

    Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2089    Accepted Submission(s): 702

    Problem Description
    Harry Potter notices some Death Eaters try to slip into Castle. The Death Eaters hide in the most depths of Forbidden Forest. Harry need stop them as soon as.

    The Forbidden Forest is mysterious. It consists of N nodes numbered from 0 to N-1. All of Death Eaters stay in the node numbered 0. The position of Castle is node n-1. The nodes connected by some roads. Harry need block some roads by magic and he want to minimize the cost. But it’s not enough, Harry want to know how many roads are blocked at least.
     
    Input
    Input consists of several test cases.

    The first line is number of test case.

    Each test case, the first line contains two integers n, m, which means the number of nodes and edges of the graph. Each node is numbered 0 to n-1.

    Following m lines contains information about edges. Each line has four integers u, v, c, d. The first two integers mean two endpoints of the edges. The third one is cost of block the edge. The fourth one means directed (d = 0) or undirected (d = 1).

    Technical Specification

    1. 2 <= n <= 1000
    2. 0 <= m <= 100000
    3. 0 <= u, v <= n-1
    4. 0 < c <= 1000000
    5. 0 <= d <= 1
     
    Output
    For each test case:
    Output the case number and the answer of how many roads are blocked at least.
     
    Sample Input
    3
     
     
    4 5
    0 1 3 0
    0 2 1 0
    1 2 1 1
    1 3 1 1
    2 3 3 1
    6 7
    0 1 1 0
    0 2 1 0
    0 3 1 0
    1 4 1 0
    2 4 1 0
    3 5 1 0
    4 5 2 0
    3 6
    0 1 1 0
    0 1 2 0
    1 1 1 1
    1 2 1 0
    1 2 1 0
    2 1 1 1
     
    Sample Output
    Case 1: 3
    Case 2: 2
    Case 3: 2
     
    Author
    aMR @ WHU
     
    Source

    题目链接:HDU 3987

    题意就是在最小割的前提下求最少的割边数,把非0流量边放大,设$maxcap$为可能出现的最大流量值(最好为10的倍数方便计算),变成$cap = cap * maxcap + 1$,0流量的肯定是不能放大的,否则出现1个流量了。

    这样一来不会改变边的大小关系,但是流量蕴含了边数,求得的最小割一定由最少割边数构成,最后求得的最小割就是$maxflow/maxcap$,最小割边数就是$maxflow\%maxcap$。

    代码:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 1010;
    const int M = 200010;
    struct edge
    {
        int to, nxt;
        LL cap;
        edge() {}
        edge(int _to, int _nxt, LL _cap): to(_to), nxt(_nxt), cap(_cap) {}
    };
    edge E[M << 1];
    int head[N], tot, d[N];
    
    void init()
    {
        CLR(head, -1);
        tot = 0;
    }
    inline void add(int s, int t, LL cap)
    {
        E[tot] = edge(t, head[s], cap);
        head[s] = tot++;
        E[tot] = edge(s, head[t], 0LL);
        head[t] = tot++;
    }
    int bfs(int s, int t)
    {
        CLR(d, -1);
        d[s] = 0;
        queue<int>Q;
        Q.push(s);
        while (!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for (int i = head[u]; ~i; i = E[i].nxt)
            {
                int v = E[i].to;
                if (d[v] == -1 && E[i].cap > 0LL)
                {
                    d[v] = d[u] + 1;
                    if (v == t)
                        return 1;
                    Q.push(v);
                }
            }
        }
        return ~d[t];
    }
    LL dfs(int s, int t, LL f)
    {
        if (s == t || !f)
            return f;
        LL ret = 0LL;
        for (int i = head[s]; ~i; i = E[i].nxt)
        {
            int v = E[i].to;
            if (d[v] == d[s] + 1 && E[i].cap > 0LL)
            {
                LL df = dfs(v, t, min<LL>(f, E[i].cap));
                if (df > 0LL)
                {
                    E[i].cap -= df;
                    E[i ^ 1].cap += df;
                    ret += df;
                    f -= df;
                    if (!f)
                        break ;
                }
            }
        }
        if (!ret)
            d[s] = -1;
        return ret;
    }
    LL dinic(int s, int t)
    {
        LL ret = 0LL;
        while (bfs(s, t))
            ret += dfs(s, t, 0x3f3f3f3f3f3f3f3f);
        return ret;
    }
    int main(void)
    {
        int tcase;
        scanf("%d", &tcase);
        for (int q = 1; q <= tcase; ++q)
        {
            init();
            int n, m, i;
            scanf("%d%d", &n, &m);
            for (i = 0; i < m; ++i)
            {
                int u, v, d;
                LL c;
                scanf("%d%d%I64d%d", &u, &v, &c, &d);
                if (c)
                    c = c * 1000000LL + 1LL;
                add(u, v, c);
                if (d)
                    add(v, u, c);
            }
            printf("Case %d: %I64d
    ", q, dinic(0, n - 1) % 1000000LL);
        }
        return 0;
    }
  • 相关阅读:
    免费报表工具 积木报表(JiMuReport)的安装
    jeecgboot积木报表(jimuReport)SQL Server切换
    Machine Learning目录
    Pytorch05_torch安装(GPU版)
    Pytorch04_RNN结构
    Pytorch03_张量变化
    Pytorch02_GPU加速
    Pytorch01_通用结构
    怎么将本地文件上传到远程git仓库
    SpringCloud-微服务架构编码构建
  • 原文地址:https://www.cnblogs.com/Blackops/p/6385713.html
Copyright © 2011-2022 走看看