题意:
      给你一个有向图,问你从1到n的最大流是多少?如果流量大于等于C那么直接输出一个串,否则输出只扩充一条边的流量就可以达到1->n大于等于C的所有边,如果扩充不了就

输出另一个串。

Sample Input                            
4 4 5
1 2 5
1 3 5
2 4 5
3 4 5
4 4 5
1 2 1
1 3 5
2 4 5
3 4 1
4 4 5
1 2 1
1 3 1
2 4 1
3 4 1
0 0 0

Output for Sample Input
Case 1: possible
Case 2: possible option:(1,2),(3,4)
Case 3: not possible

 
思路:
      很容易想到的一点就是扩展后有作用的点肯定是割边,那么我们可以先跑一遍最大流把割边找出来,然后枚举割边,扩充割边流量,看最大流是否大于等于C,但是这样会TLE,有两个比较有用的优化,就是每次都在残余网络上改流量,然后加上残余网络之前跑出来的流量,还有一个优化就是跑最大流的时候,如果当前流量大于等于C了就已经满足了,没必要再跑了。

#include<queue>

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N_node 100 + 5

#define N_edge 20000 + 10

#define INF 2005000000

using namespace std;

typedef struct

{

   int from ,to ,next;

   long long  cost;

}STAR;

typedef struct

{

   int x ,t;

}DEP;

typedef struct

{

   int a ,b;

}EDGE;

STAR E[N_edge] ,mkE[N_edge];

EDGE edge[N_edge] ,Ans_Edge[N_edge];

DEP xin ,tou;

int list[N_node] ,list2[N_node] ,mklist[N_node] ,tot;

int deep[N_node];

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

{

   E[++tot].from = a;

   E[tot].to = b;

   E[tot].cost = c;

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

   list[a] = tot;

   

   E[++tot].from = b;

   E[tot].to = a;

   E[tot].cost = 0;

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

   list[b] = tot;

}

bool camp(EDGE a ,EDGE b)

{

   return a.a < b.a || a.a == b.a && a.b < b.b;

}

long long minn(long long a ,long long b)

{

   return a < b ? a : b;

}

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

{

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

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

   deep[s] = 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 ++)

   list2[i] = list[i];

   return deep[t] != -1;

}

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

{

   if(s == t) return flow;

   long long nowflow = 0;

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

   {

      list2[s] = k;

      int to = E[k].to;

      long long c = E[k].cost;

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

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

      nowflow += tmp;

      E[k].cost -= tmp;

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

      if(nowflow == flow) break;

   }

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

   return nowflow;

}

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

{

   long long Ans = 0;

   while(BFS_Deep(s ,t ,n) && Ans < C)

   {

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

   }

   return Ans;

}

int main ()

{

   int n ,m ,C ,cas = 1;

   int a ,b ,c ,i ,j;

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

   {

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

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

      {

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

         add(a ,b ,(long long)c);

      }

      long long Ans = DINIC(1 ,n ,n ,C);

      printf("Case %d: " ,cas ++);

      if(Ans >= C) 

      {

         printf("possible\n");

         continue;

      }

      int nowid = 0;

      for(i = 2 ;i <= tot ;i += 2)

      {

         mkE[i] = E[i] ,mkE[i+1] = E[i+1];

         if(!E[i].cost)

         {

            edge[++nowid].a = E[i].from;

            edge[nowid].b = E[i].to;

         }

      }

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

      mklist[i] = list[i];

      

      int Ans_Id = 0;

      int mktot = tot;

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

      {

         add(edge[i].a ,edge[i].b ,C);

         long long tmp = DINIC(1 ,n ,n ,C);

         if(tmp + Ans >= C) Ans_Edge[++Ans_Id] = edge[i];

         tot = mktot;

         for(j = 2 ;j <= tot ;j ++)  E[j] = mkE[j];

         for(j = 1 ;j <= n ;j ++) list[j] = mklist[j];

         

      }

      if(!Ans_Id)

      {

         puts("not possible");

         continue;

      }

      sort(Ans_Edge + 1 ,Ans_Edge + Ans_Id + 1 ,camp);

      printf("possible option:");

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

      if(i != 1) printf(",(%d,%d)" ,Ans_Edge[i].a ,Ans_Edge[i].b);

      else  printf("(%d,%d)" ,Ans_Edge[i].a ,Ans_Edge[i].b);

      puts("");

   }

   return 0;

}

UVA11248 网络扩容(枚举割边扩充)的更多相关文章

  1. C++之路进阶——codevs1362(网络扩容)

    1362 网络扩容 省队选拔赛  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 给定一张有向图,每条边都有一个容量 ...

  2. BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 2269 Solved: 1136 [Submit ...

  3. 【BZOJ】【1834】【ZJOI2010】Network 网络扩容

    网络流/费用流 这题……我一开始sb了. 第一问简单的最大流…… 第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建…… 我们令残量网络上原有的弧的费用全部为0(因为 ...

  4. bzoj1834: [ZJOI2010]network 网络扩容

    努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> ...

  5. BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)

    第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然  后跑最小费用最大流就OK了. ---- ...

  6. 【BZOJ1834】网络扩容(最大流,费用流)

    [BZOJ1834]网络扩容(最大流,费用流) 题面 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下 ...

  7. BZOJ_1834_[ZJOI2010]network 网络扩容_费用流

    BZOJ_1834_[ZJOI2010]network 网络扩容_费用流 题意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求:  1.在不扩容的 ...

  8. 【题解】Luogu P2604 [ZJOI2010]网络扩容

    原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...

  9. 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

    [BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...

随机推荐

  1. pandas函数的使用

    一.Pandas的数据结构 1.Series Series是一种类似与一维数组的对象,由下面两个部分组成: values:一组数据(ndarray类型) index:相关的数据索引标签 1)Serie ...

  2. FreeRedis分布式锁实现以及使用

    前言 今日上班听到同事在准备面试题分布式锁(准备溜溜球),随即加入了群聊复习了一波,于是有了这篇小作文. 场景 本文中的演示 DEMO, 以下订单减库存为例. 无锁裸奔表现 示例代码: 先来模拟一个库 ...

  3. FreeBSD 12.2 vmware 虚拟机镜像 bt 种子

    安装了 KDE5 火狐浏览器 Fcitx 输入法 并进行了中文设置 替换软件源为国内可用. VirtualBox虚拟机也可以用  magnet:?xt=urn:btih:E88885631B57426 ...

  4. Hibernate在oracle中ID增长的方式(续)

    引用链接:http://blog.csdn.net/w183705952/article/details/7367272 第二种:设置ID的增长策略是native,但是需要创建一个名字为hiberna ...

  5. P2731 骑马修栅栏 Riding the Fences 题解(欧拉回路)

    题目链接 P2731 骑马修栅栏 Riding the Fences 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...

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

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

  7. 利用kali系统制作最简单的OS

    制作最简单的OS 一.生成.bin文件 1.创建Boot.asm文件,输入相应的汇编代码 org 07c00h ; mov ax, cs mov ds, ax mov es, ax call Disp ...

  8. 2019HDU多校第七场 HDU6646 A + B = C 【模拟】

    一.题目 A + B = C 二.分析 比较考验码力的题. 对于$c$,因为首位肯定不为0,那么$a$或者$b$至少有一个最高位是和$c$平齐的,或者少一位(相当于$a$+$b$进位得到). 那么这里 ...

  9. Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

    一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...

  10. PTA 求链式表的表长

    6-1 求链式表的表长 (10 分)   本题要求实现一个函数,求链式表的表长. 函数接口定义: int Length( List L ); 其中List结构定义如下: typedef struct ...