题意:
      是让你求最小割之后问最小割的最少边数是多少,因为最小割不是唯一的,所以存在最小边数的问法。

思路:
      两个方法,一个是先一遍最大流,然后把割边全都改成流量1,其他的全都改成流量无穷就行了,第二个方法是比较经典的方法,就是把权值放大 *(E+1)+1,最后在对(E+1)取余就行了,这么干其实是同时跑了两遍最大流,只不过是两个权值之间的差距太大,不会相互影响。

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 1000 + 5

#define N_edge 400000 + 100

#define INF 2055000000

using namespace std;

typedef struct

{

   int from ,to ,next;

   long long  cost;

}STAR;

typedef struct

{

   int x ,t;

}DEP;

STAR E[N_edge];

DEP xin ,tou;

int list[N_node] ,list2[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;

}

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)

{

   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));

      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 Ans = 0;

   while(BFS_Deep(s ,t ,n))

   {

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

   }

   return Ans;

}

int main ()

{

    int a ,b ,c ,d;

    int t ,n ,m ,i ,cas = 1;

    scanf("%d" ,&t);

    while(t--)

    {

        scanf("%d %d" ,&n ,&m);

        memset(list ,0 ,sizeof(list));

        tot = 1;

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

        {

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

           if(d) add(a + 1 ,b + 1 ,(long long)c) ,add(b + 1 ,a + 1 ,c);

           else add(a + 1 ,b + 1 ,(long long)c);

        }

        DINIC(1 ,n ,n);

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

        if(!E[i].cost) E[i].cost = 1 ,E[i^1].cost = 0;

        else E[i].cost = INF ,E[i^1].cost = 0;

        printf("Case %d: %lld\n" ,cas ++ ,DINIC(1 ,n ,n));

     }

     return 0;

}     

    

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 1000 + 5

#define N_edge 400000 + 100

#define INF 205500000000000//这个地方记得开大点,因为放大了权值

using namespace std;

typedef struct

{

   int from ,to ,next;

   long long  cost;

}STAR;

typedef struct

{

   int x ,t;

}DEP;

STAR E[N_edge];

DEP xin ,tou;

int list[N_node] ,list2[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;

}

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)

{

   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));

      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 Ans = 0;

   while(BFS_Deep(s ,t ,n))

   {

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

   }

   return Ans;

}

int main ()

{

    int a ,b ,c ,d;

    int t ,n ,m ,i ,cas = 1;

    scanf("%d" ,&t);

    while(t--)

    {

        scanf("%d %d" ,&n ,&m);

        memset(list ,0 ,sizeof(list));

        tot = 1;

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

        {

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

           if(d) add(a + 1 ,b + 1 ,(long long)c * 100001 + 1) ,add(b + 1 ,a + 1 ,(long long)c * 100001 + 1);

           else add(a + 1 ,b + 1 ,(long long)c * 100001 + 1);

        }

        printf("Case %d: %lld\n" ,cas ++ ,DINIC(1 ,n ,n) % 100001);

     }

     return 0;

}     

    

    
    
    

    
    
    

hdu3987 最小割边数的更多相关文章

  1. 2017青岛赛区网络赛 Smallest Minimum Cut 求最小割的最小割边数

    先最大流跑一遍 在残存网络上把满流边容量+1 非满流边容量设为无穷大 在进行一次最大流即可 (这里的边都不包括建图时用于反悔的反向边) #include<cstdio> #include& ...

  2. HDU - 6214:Smallest Minimum Cut(最小割边最小割)

    Consider a network G=(V,E) G=(V,E) with source s s and sink t t . An s-t cut is a partition of nodes ...

  3. 剑指OFFER之把数组排成最小的数(九度OJ1504)

    题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输 ...

  4. 九度OJ 1504 把数组排成最小的数【算法】-- 2009年百度面试题

    题目地址:http://ac.jobdu.com/problem.php?pid=1504 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如 ...

  5. 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。

    http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...

  6. 《剑指offer》第四十五题(把数组排成最小的数)

    // 面试题45:把数组排成最小的数 // 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼 // 接出的所有数字中最小的一个.例如输入数组{3, 32, 321},则打印出这3 ...

  7. 《剑指offer》— JavaScript(32)把数组排成最小的数

    把数组排成最小的数 题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为3213 ...

  8. 2015 湘潭大学程序设计比赛(Internet)--D题-最小的数

    最小的数 Accepted : 47   Submit : 276 Time Limit : 1000 MS   Memory Limit : 65536 KB 题目描述 给你一个n位数,每次操作可以 ...

  9. C语言:输入10个整数,找出其中绝对值最小的数

    1 输入10个整数,找出其中绝对值最小的数(10分) 题目描述 输入10个整数,找出其中绝对值最小的数 输入 十个整数 输出 绝对值最小的数 样例输入 -10 -2 30 40 50 60 70 80 ...

随机推荐

  1. 002-LED闪烁

    LED闪烁 功能:控制LED模块的小灯闪烁 #include<reg52.h> // 头文件 sbit LED = P2^0; // LED接低电平 void main() //主函数 { ...

  2. HDOJ-1213(简单并查集)

    How many tables HDOJ-1213 #include<iostream> #include<cstring> #include<cstdio> #i ...

  3. Linux发行版及其目标用户

    1.Debian Debian 众所周知,是Deepin,Ubuntu和Mint等流行Linux发行版的母亲,这些发行版提供了可靠的性能,稳定性和无与伦比的用户体验.最新的稳定发行版是Debian 1 ...

  4. SpringBoot 访问jsp文件报错Path with "WEB-INF" or "META-INF": [WEB-INF/jsp/welcome.jsp]的解决办法

    由于SpringBoot不在支持jsp,所以想使用jsp的情况下需要在pom.xml配置servlet依赖,jstl标签库和tomcat依赖.以下是我的pom.xml的配置: (ps:标记红色处为重点 ...

  5. MySQL入门(6)——流程控制

    MySQL入门(6)--流程控制 IF语句 条件判断语句,逻辑与大多数编程语言相同,表示形式如下: IF condition THEN ... [ELSE condition THEN] ... [E ...

  6. 关于asyncio知识一

    一.介绍 asyncio 是python3.4 引入的一个新的并发模块,主要通过使用coroutines 和 futures 来让我们更容易的去实现异步的功能,并且几乎和写同步代码一样的写代码,还没有 ...

  7. clickhouse 亿级数据性能测试

    clickhouse 在数据分析技术领域早已声名远扬,如果还不知道可以 点这里 了解下. 最近由于项目需求使用到了 clickhouse 做分析数据库,于是用测试环境做了一个单表 6 亿数据量的性能测 ...

  8. webgoat白盒审计+漏洞测试

    前言 小白,记录,有问题可以交流 乖乖放上参考链接: https://www.freebuf.com/column/221947.html https://www.sec-un.org/java代码审 ...

  9. HashMap源码个人解读

    HashMap的源码比较复杂,最近也是结合视频以及其余大佬的博客,想着记录一下自己的理解或者当作笔记 JDK1.8后,HashMap底层是数组+链表+红黑树.在这之前都是数组+链表,而改变的原因也就是 ...

  10. markdown快捷输入

    标题: 输入方式:#+空格+标题名,几级标题就敲几个# 注:最大支持六级标题 字体 加粗:在要加粗的字体前后加** 斜体:在要倾斜的字体前后加* 斜体加粗:在要倾斜并加粗的字体前后加*** 删除线:在 ...