题意:

      有n个猪圈,每个猪圈里面都有一定数量的猪(可能大于当前猪圈的数量),每个猪圈都有自己的容量,猪圈与猪圈之间给出了距离,然后突然下雨了,问多久之后所有的猪都能进圈。

思路:

       先跑一遍Floyd求出任意两点之间的最短距离,对于时间,也就是答案,我们可以二分去找,然后对于每次二分,我们可以用DINIC去判断是否满足要求,建图的时候记得拆点,一开始我感觉不用抄点,但是都敲完了,发现不行,又重新建图了,拆成二分图,然后根据当前二分的值连边。。。这个题比较简单,没啥难点,就是长时间没写了,练练手,还有提醒一点,二分的时候可以不直接二分时间,我们可以吧所有可能的时间都找出来,排序,离散化一下,这样直接二分下标,减少时间开销(直接不离散化目测也行,但是离散化能更快点)。下面是我的代码,用的方法是
Floyd+离散化+二分+DINIC做的,这个题思路不难,就是练练手,就解释这么多。

      

#include<queue>

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N_node 400 + 10

#define N_edge (200 * 200 + 400) * 2 + 100

#define INF 2000000000

#define III 0x3f3f3f3f3f3f3f3f

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int x ,t;

}DEP;

DEP xin ,tou;

STAR E[N_edge];

int list[N_node] ,listt[N_node] ,tot;

int deep[N_node];

long long map[202][202];

long long tmp[50000] ,num[50000];

int L[202] ,R[202];

int S;

void add(int a ,int b ,int c)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].to = a;

    E[tot].cost = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

int minn(int x ,int y)

{

    return x < y ? x : y;

}

void Floyd(int n)

{

    for(int k = 1 ;k <= n ;k ++)

    for(int i = 1 ;i <= n ;i ++)

    for(int j = 1 ;j <= n ;j ++)

    if(map[i][j] > map[i][k] + map[k][j])

    map[i][j] = map[i][k] + map[k][j];

}

bool BFS_Deep(int s ,int t ,int n)

{

    memset(deep ,255 ,sizeof(deep));

    deep[s] = 0;

    xin.x = s ,xin.t = 0;

    queue<DEP>q;

    q.push(xin);

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int k = list[tou.x] ;k ;k = E[k].next)

        {

            xin.x = E[k].to;

            xin.t = tou.t + 1;

            if(deep[xin.x] != -1 || !E[k].cost)

            continue;

            deep[xin.x] = xin.t;

            q.push(xin);

        }

    }

    for(int i = 0 ;i <= n ;i ++)

    listt[i] = list[i];

    return deep[t] != -1;

}

int DFS_Flow(int s ,int t ,int flow)

{

    if(s == t) return flow;

    int nowflow = 0;

    for(int k = listt[s] ;k ;k = E[k].next)

    {

        listt[s] = k;

        int to = E[k].to;

        int c = E[k].cost;

        if(deep[to] != deep[s] + 1 || !c)

        continue;

        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));

        nowflow += tmp;

        E[k].cost -= tmp;

        E[k^1].cost += tmp;

        if(flow == nowflow) break;

    }

    if(!nowflow) deep[s] = 0;

    return nowflow;

}

int DINIC(int s ,int t ,int n)

{

    int Ans = 0;

    while(BFS_Deep(s ,t ,n))

    {

        Ans += DFS_Flow(s ,t ,INF);

    }

    return Ans;

}

void Buid(int n ,long long mid)

{

    memset(list ,0 ,sizeof(list)) ,tot = 1;

    for(int i = 1 ;i <= n ;i ++)

    add(0 ,i ,L[i]) ,add(i + n ,n + n + 1 ,R[i]);

    for(int i = 1 ;i <= n ;i ++)

    for(int j = 1 ;j <= n ;j ++)

    if(map[i][j] <= mid) add(i ,j + n ,INF);

}

long long solve(int n)

{

    int t = 0;

    for(int i = 1 ;i <= n ;i ++)

    for(int j = i ;j <= n ;j ++)

    if(map[i][j] != III) tmp[++t] = map[i][j];

    sort(tmp + 1 ,tmp + t + 1);

    int numn = 0;

    for(int i = 1 ;i <= t ;i ++)

    if(i == 1 || tmp[i] != tmp[i-1])

    num[++numn] = tmp[i];

    int low = 1 ,up = numn ,mid;

    long long Ans = -1;

    while(low <= up)

    {

        mid = (low + up) >> 1;

        Buid(n ,num[mid]);

        if(DINIC(0 ,n + n + 1 ,n + n + 1) == S)

        {

            Ans = num[mid];

            up = mid - 1;

        }else low = mid + 1;

    }

    return Ans;

}

int main ()

{

    int n ,m ,i ,j;

    long long a ,b ,c;

    while(~scanf("%d %d" ,&n ,&m))

    {

        for(S = 0 ,i = 1 ;i <= n ;i ++)

        {

            scanf("%d %d" ,&L[i] ,&R[i]);

            S += L[i];

        }

        for(i = 1 ;i <= n ;i ++)

        {

            for(j = i + 1;j <= n ;j ++)

            map[i][j] = map[j][i] = III;

            map[i][i] = 0;

        }

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%lld %lld %lld" ,&a ,&b ,&c);

            if(map[a][b] > c) map[a][b] = map[b][a] = c;

        }

        Floyd(n);

        long long Ans = solve(n);

        printf("%lld\n" ,Ans);

    }

    return 0;

}

POJ2391 Floyd+离散化+二分+DINIC的更多相关文章

  1. poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap

    poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 ...

  2. [Codeforces 1199C]MP3(离散化+二分答案)

    [Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...

  3. Optimal Milking(POJ2112+二分+Dinic)

    题目链接:http://poj.org/problem?id=2112 题目: 题意:有k台挤奶机,c头奶牛,每台挤奶机每天最多生产m的奶,给你每个物品到其他物品的距离(除了物品到自己本省的距离为0外 ...

  4. hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

    Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  5. POJ 3189 二分+Dinic

    题意: 思路: 二分跨度 枚举最低座次 建图:源点向每头牛连边权为1的边 每头牛向当前枚举的B的区间这段连上边权为1的边 所有座次向汇点连边权为牛棚容量的边 判判流量是不是等于n 一开始写得是直接枚举 ...

  6. 2019 Multi-University Training Contest 3 Find the answer (离散化+二分+树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 题目大意:给定一个含有n个数的序列,还有一个m,对于每个i(1<=i<=n)求出最少 ...

  7. 2019牛客暑期多校训练营(第七场)E-Find the median(思维+树状数组+离散化+二分)

    >传送门< 题意:给n个操作,每次和 (1e9范围内)即往数组里面插所有 的所有数,求每次操作后的中位数思路:区间离散化然后二分答案,因为小于中位数的数字恰好有个,这显然具有单调性.那么问 ...

  8. Codeforces Round #521 (Div. 3) E. Thematic Contests (离散化,二分)

    题意:有\(n\)个话题,每次都必须选取不同的话题,且话题数必须是上次的两倍,第一次的话题数可以任意,问最多能选取多少话题数. 题解:我们首先用桶来记录不同话题的数量,因为只要求话题的数量,与话题是多 ...

  9. nyoj-310-河南省第四届省赛题目-二分+dinic

    SECRET 时间限制:3000 ms  |  内存限制:65535 KB 难度:6   描述 Dr.Kong is constructing a new machine and wishes to ...

随机推荐

  1. Mybatis系列全解(六):Mybatis最硬核的API你知道几个?

    封面:洛小汐 作者:潘潘 2020 年的大疫情,把世界撕成几片. 时至今日,依旧人心惶惶. 很庆幸,身处这安稳国, 兼得一份安稳工. · 东家常讲的一个词:深秋心态 . 大势时,不跟风.起哄, 萧条时 ...

  2. 链表算法题之中等级别,debug调试更简单

    文章简述 大家好,本篇是个人的第 5 篇文章 从本篇文章开始,分享关于链表的题目为中等难度,本次共有 3 道题目. 一,两数相加 1.1 题目分析 题中写到数字是按照逆序的方式存储,从进位的角度看,两 ...

  3. 通达OA 页面敏感信息-2013/2015版本

    参考 http://wiki.0-sec.org/0day/%E9%80%9A%E8%BE%BEoa/4.html 漏洞影响 2013.2015版本 复现过程 POC: http://0-sec.or ...

  4. JAVA_标识符、数据类型、变量

    标识符和关键字 ​ 所有的标识符否应该以字母a ~ z和 A ~Z ,美元符($).下划线(_)开始. ​ 首字符之后可以是字母a ~ z和 A ~Z ,美元符($).下划线(_)的任意字符组合. 注 ...

  5. 记一次jstack命令定位问题

    今天天气不错,但是赶上恶意加班心情就不爽,怀着不爽的心情干活,总能创造出更多的问题,这不,今天就自己挖了一个坑,自己跳进去了,好在上来了 经过是这样的,开始调试canal采集binlog时,由于添加了 ...

  6. JS逆向-抠代码的第一天【手把手学会抠代码】

    首先声明,本人经过无数次摸爬滚打及翻阅各类资料,理论知识极其丰富,但是抠代码怎么都抠不会. 无奈之下,只能承认:这个活,需要熟练度. 本文仅对部分参数进行解析,有需要调用,请自行根据现实情况调整. 第 ...

  7. Go语言学习笔记——Go语言的指针

    Go具有指针.指针保存了变量的内存地址. 类型*T是指向类型T的值得指针.其零值是nil var p *int &符号会生成一个指向其作用对象的指针 i:=42 P=&i *符号表示指 ...

  8. Codeforces 1015E1 Stars Drawing (Easy Edition)

    题面: 传送门 题目描述: 要求用十字星星来画题目给出的"星"图.如果不能用十字星星来画"星"图,输出-1:如果能,则输出要在图的哪个位置画相应大小的十字星图. ...

  9. FIL怎么获得?FIL在哪里购买?

    从一些交易网站可以看到,FIL 这几天有一个比较大的涨幅,这让许多投资 FIL 的朋友大松一口气:FIL,你终于不装睡了.估计许多关注区块链的小伙伴看到消息又要问了:FIL 怎么获得?FIL 在哪里购 ...

  10. 使用MyBatis的步骤

    1.创建空的Java工程,安装MyBatis依赖 <?xml version="1.0" encoding="UTF-8"?> <projec ...