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

思路:
      两个方法,一个是先一遍最大流,然后把割边全都改成流量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. 40. 组合总和 II + 递归 + 回溯 + 记录路径

    40. 组合总和 II LeetCode_40 题目描述 题解分析 此题和 39. 组合总和 + 递归 + 回溯 + 存储路径很像,只不过题目修改了一下. 题解的关键是首先将候选数组进行排序,然后记录 ...

  2. POJ-1321棋盘问题(简单深搜)

    简单搜索step1 POJ-1321 这是第一次博客,题目也很简单,主要是注意格式书写以及常见的快速输入输出和文件输入输出的格式. 递归的时候注意起始是从(-1,-1)开始,然后每次从下一行开始递归. ...

  3. RichTextBox FlowDocument类型操作

      最近研究微信项目,套着web版微信协议做了一个客户端,整体WPF项目MVVM架构及基本代码参考于:http://www.cnblogs.com/ZXdeveloper/archive/2016/1 ...

  4. Python数据格式:%s字符串,%d整型,%f浮点型

    格式化符% name="Tom" age=int(input("age")) pt2="%s你的年龄是%d"%(name,age) prin ...

  5. 一文搞懂 this、apply、call、bind

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14506269.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  6. FreeBSD 中文TTY控制台

    freebsd新型终端VT,支持cjk,所以丢个字体进去,就能显示中文了1,首先你没有改过控制台程序,使用的是默认的,,2,最新版本,本说明是以freebsd12.1release字体格式为.fnt命 ...

  7. 200-Java语言基础-Java编程入门-005 | Java方法定义及使用

    一.方法概述和格式说明 为什么要用方法: 提高代码的复用性 什么是方法: 完成特定功能的代码块 方法的格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) {     方 ...

  8. js 检测当前浏览其类型

    需求:检测并打印当前使用的浏览器类型 <script type="text/javascript"> function getBrowser(){ const str ...

  9. 深入理解Java并发框架AQS系列(一):线程

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.概述 1.1.前言 重剑无锋,大巧不工 读j.u.c包下的源码,永远无法绕开的经典 ...

  10. python爬虫加定时任务,制作微信提醒备忘录

    一.任务的记录与提取 1.1 制作每日任务 为了便于爬取,推荐使用网页版的在线记事本,现在这种工具很多,我选择"石墨文档"进行操作演示.记录内容的 格式可以根据自己的需求和爬虫自行 ...