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

思路:
      两个方法,一个是先一遍最大流,然后把割边全都改成流量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. 1.1 Python3基础-前言

    >>返回主目录 Python 交互式代码 Python 脚本式代码 第一段Python代码: print('Hello World!') >>返回主目录

  2. Linux速通07 硬盘分区、格式化及文件系统管理

    硬件设备与文件名的对应关系 # 在Linux系统中,每个设备都被当作一个文件来对待 # 各种设备在Linux中的文件名 设备 设备在Linux内的文件名 IDE硬盘 /dev/hd[a-d] SCSI ...

  3. SpringMVC-06 Ajax

    SpringMVC-06 Ajax Ajax 1.简介 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 是一种在无 ...

  4. 修饰符static和abstract

    修饰符static和abstract static static可以修饰类中的方法,属性等,被修饰后的方法和属性可以通过类名直接调用也可以通过对象调用.普通的变量只能通过对象进行调用. 静态方法直接可 ...

  5. find文本处理(locate)实例学习记录

    find文本处理(locate)实例学习记录 (一)按文件名称查找 按照文件名称查找是 find 最常见的用法,需要注意的是,搜索的文件名必须完全匹配,才能找到对应的文件. 1. 查找当前目录下所有 ...

  6. WM_CLOSE WM_QUIT WM_DESTROY 三者的区别

    一 个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出.你知道让用户作确认或 有错误出现或有什么应该注意的事情发生的时候,往往弹 ...

  7. FutureTask核心源码分析

    本文主要介绍FutureTask中的核心方法,如果有错误,欢迎大家指出! 首先我们看一下在java中FutureTask的组织关系 我们看一下FutureTask中关键的成员变量以及其构造方法 //表 ...

  8. RabbitMQ 入门 (Go) - 4. 使用 Fanout Exchange 做服务发现(上)

    到目前为止,我们项目的结果大致如下: 传感器生成的模拟数据(包含传感器名称.数据.时间戳)是通过传感器在运行时动态创建的 Queue 来发送的.这些 Queue 很难直接被发现. 为了解决这个问题,我 ...

  9. WebGPU[4] 纹理三角形

    代码见:https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/04-texture-triangle 原创,发布日 202 ...

  10. 【linux】驱动-8-一文解决设备树

    目录 前言 8. Linux设备树 8.1 设备树简介 8.2 设备树框架 8.2.1 设备树格式 8.2.1.1 DTS 文件布局 8.2.1.2 node 格式 8.2.1.3 propertie ...