题意:
      有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 - 3179 Corral the Cows(离散化+二分+二维前缀和)

    题目链接:点击查看 题目大意:在二维平面中给出n个点,每个位置都有一个一个三叶草,现在需要求出一个长方形区域,要求长方形边长最短,并且面积内部包含至少C个三叶草 题目分析:题目给出的n最大为500,但 ...

  2. POJ 3179Corral the Cows(离散化+二分)

    题目链接: http://poj.org/problem?id=3179 题意: 有一个最大为10000的图,里面有一些特定的点叫三叶草,每个这样的点可包括往上.右.右上(也就是这是单位矩形的左下角) ...

  3. POJ3179 Corral the Cows 离散化 二分 前缀和

    题目链接 http://poj.org/problem?id=3179 分析 容易想到二分和前缀和,难点在于坐标离散化,要将横纵坐标分别离散化. 对于三叶草的每个坐标,将其映射为次序: 没有三叶草的位 ...

  4. 【codevs1422】河城荷取 二分+dinic

    题目描述 Description 在幻想乡,河城荷取是擅长高科技工业的河童.荷取的得意之作除了光学迷彩外,还有震动整个幻想乡的巨型人形『非想天则』.不过由于人形太过巨大,所以为它充能是一件很麻烦的事. ...

  5. Gym - 100519 B Bring Your Own Bombs 离散化+二分+思维

    题目链接:https://vjudge.net/contest/370255#problem/B 我们考虑每一行每一列会爆炸的概率是多少  显然 对于会爆炸的每一行 位于该行的矩形的长都会爆炸  对于 ...

  6. POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)

    [题意]有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点. 和POJ2112很类 ...

  7. [总结]2019年9月 OI学习/刷题记录

    从现在开始记录一下每天的学习情况.主力LOJ? 2019/9/5 LibreOJ #2543. 「JXOI2018」排序问题 答案显然是\(\frac{(n+m)!}{Cnt_1!Cnt_2!\cdo ...

  8. 题解 P1682 【过家家】

    P1682 过家家 题目描述 有2n个小学生来玩过家家游戏,其中有n个男生,编号为1到n,另外n个女生,编号也是1到n.每一个女生可以先选择一个和她不吵嘴的男生来玩,除此之外,如果编号为X的女生的朋友 ...

  9. Codeforces Global Round 2 D. Frets On Fire (动态开点线段树,沙雕写法)

    题目链接:D. Frets On Fire 思路:明明可以离散化+二分写,思路硬是歪到了线段树上,自闭了,真实弟弟,怪不得其他人过得那么快 只和查询的区间长度有关系,排完序如果相邻的两个点的差值小于等 ...

最新文章

  1. 学习Exchange管理最佳实践
  2. hdu 1280用hash解决。。
  3. 文本聊天室(TCP-中)
  4. 100个最古老互联网域名 最久只有23年(附名单)
  5. 自学Python:截取屏幕画面
  6. Yocto tips (17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
  7. 生成xml_freemarker快速生成xml文件
  8. 马尔可夫随机场数学原理理解
  9. 一次网站登录慢故障排查
  10. ios的Navigation Controller的学习使用
  11. 物体检测算法:R-CNN,SSD,YOLO 动手学深度学习v2 pytorch
  12. 如何连接linux服务器
  13. QTP软件测试工具学习
  14. 液压系统仿真软件_利用仿真软件判断系统稳定
  15. Windows10系统把JDK安装到D盘上的步骤及安装
  16. DBeaver复制数据库报错@@GLOBAL.GTID_PURGED cannot be changed: the added gtid set must not overlap with @@GLO
  17. 3.3V的稳压管,结果电压变成了2.5V
  18. 微信隐藏功能:群接龙
  19. 怀揣梦想,我依靠自己,往后余生越来越精彩
  20. 问题 D: 猫和兔子

热门文章

  1. 百篇大计敬本年之系统篇《八》—— Ubuntu16.04 挂载windows的 NTFS 文件系统时错误的解决方法...
  2. [Android Pro] InputStream.skip方法的思考
  3. 30个最常用css选择器解析
  4. 给你的Flex程序添加深链接和分析-其实比你想象的要简单
  5. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)...
  6. 极虎病毒创造四个“之最”
  7. Tomcat的manager APP设置
  8. iptables日志探秘
  9. hdu5643 King's Game(约瑟夫环+线段树)
  10. 【mysql】关于事务的隔离级别