题意:
      给你一个有向图,问你从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. dubbo实战之一:准备和初体验

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树

    洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...

  3. (数据科学学习手札110)Python+Dash快速web应用开发——静态部件篇(下)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  4. 在Asp.Net Core 5 中使用EF Core连接MariaDB

    升级到Asp.Net Core 5,使用EF Core连接MariaDB,使用的Nuget包Pomelo.EntityFrameworkCore.MySql也升级到了5.0.0-alpha.2,然后发 ...

  5. E - Recursive sequence HDU - 5950 (矩阵快速幂)

    题目链接:https://vjudge.net/problem/HDU-5950 思路: 构造矩阵,然后利用矩阵快速幂. 1 #include <bits/stdc++.h> 2 #inc ...

  6. PTA 二叉树的三种遍历(先序、中序和后序)

    6-5 二叉树的三种遍历(先序.中序和后序) (6 分)   本题要求实现给定的二叉树的三种遍历. 函数接口定义: void Preorder(BiTree T); void Inorder(BiTr ...

  7. concurrentHashMap扩容相关方法详解

    上一个博客中说到了concurrentHashMap的put操作,在put操作之后如果添加了节点,我们首先会把全局的节点数+1,如果满足了扩容条件,我们则进行扩容 我们先从addCount方法说起 / ...

  8. 使用C# (.NET Core) 实现单体设计模式 (Singleton Pattern)

    本文的概念内容来自深入浅出设计模式一书 由于我在给公司做内培, 所以最近天天写设计模式的文章.... 单体模式 Singleton 单体模式的目标就是只创建一个实例. 实际中有很多种对象我们可能只需要 ...

  9. [Fundamental of Power Electronics]-PART II-7. 交流等效电路建模-7.4 规范电路模型

    7.4 规范电路模型 在讨论了推导开关变换器交流等效电路模型的几种方法后,让我们先停下来,说明下这些结果.所有的在 CCM下以PWM工作的DC-DC变换器都具有相似的基本功能.首先,他们在理想情况下, ...

  10. 201871030118-雷云云 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客 班级链接 这个作业要求链接 作业链接 我的课程学习目标 (1)体验软件项目开发中的两人合作,练习结对编程(2)掌握Github协作开发程序的操作方法(3)学习遗传算法 这个作 ...