题目大意:

给出一张无向图,找出T条从1..N的路径,互不重复,求走过的所有边中的最大值最小是多少。

算法讨论:

首先最大值最小就提醒我们用二分,每次二分一个最大值,然后重新构图,把那些边权符合要求的边加入新图,在新图上跑网络流。

这题有许多注意的地方:

1、因为是无向图,所以我们在加正向边和反向边的时候,流量都是1,而不是正向边是1,反向边是0。

2、题目中说这样的路径可能不止t条,所以我们在最后二分判定的时候不能写 == t,而是要 >= t。

3、这题很容易T ,表示我T了N遍,弱菜啊。

Codes:

  1. #include <cstring>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <vector>
  7. #include <queue>
  8.  
  9. using namespace std;
  10.  
  11. struct Edge{
  12. int from, to, cap, flow;
  13. Edge(int _from = , int _to = , int _cap = , int _flow = ):
  14. from(_from), to(_to), cap(_cap), flow(_flow) {}
  15. }E[ + ];
  16.  
  17. struct Dinic{
  18. static const int N = + ;
  19. static const int M = + ;
  20. static const int oo = 0x3f3f3f3f;
  21.  
  22. int n, m, s, t;
  23. vector <Edge> edges;
  24. vector <int> G[N];
  25. int dis[N], cur[N];
  26. bool vi[N];
  27.  
  28. void Clear(){
  29. for(int i = ; i <= n; ++ i) G[i].clear();
  30. edges.clear();
  31. }
  32.  
  33. void Add(int from, int to, int cap, int flow){
  34. edges.push_back((Edge){from, to, cap, });
  35. edges.push_back((Edge){to, from, cap, });
  36. int m = edges.size();
  37. G[from].push_back(m - );
  38. G[to].push_back(m - );
  39. }
  40.  
  41. bool bfs(){
  42. for(int i = ; i <= n; ++ i) vi[i] = false;
  43. dis[s] = ; vi[s] = true;
  44. queue <int> q; q.push(s);
  45.  
  46. while(!q.empty()){
  47. int x = q.front(); q.pop();
  48. for(int i = ; i < G[x].size(); ++ i){
  49. Edge &e = edges[G[x][i]];
  50. if(!vi[e.to] && e.cap > e.flow){
  51. vi[e.to] = true;
  52. dis[e.to] = dis[x] + ;
  53. q.push(e.to);
  54. }
  55. }
  56. }
  57. return vi[t];
  58. }
  59.  
  60. int dfs(int x, int a){
  61. if(x == t || a == ) return a;
  62. int flw = , f;
  63. for(int &i = cur[x]; i < G[x].size(); ++ i){
  64. Edge &e = edges[G[x][i]];
  65. if(dis[x] + == dis[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > ){
  66. e.flow += f; edges[G[x][i]^].flow -= f;
  67. a -= f; flw += f;
  68. if(!a) break;
  69. }
  70. }
  71. return flw;
  72. }
  73.  
  74. int Maxflow(int s, int t){
  75. this->s = s;this-> t = t;
  76. int flw = ;
  77. while(bfs()){
  78. memset(cur, , sizeof cur);
  79. flw += dfs(s, oo);
  80. }
  81. return flw;
  82. }
  83.  
  84. }Net;
  85.  
  86. int ns, ps, ts;
  87. int l = 0x3f3f3f3f, r, mid;
  88.  
  89. bool check(int mv){
  90. for(int i = ; i < ps; ++ i){
  91. if(E[i].cap <= mv){
  92. Net.Add(E[i].from, E[i].to, , );
  93. }
  94. }
  95. return Net.Maxflow(, Net.n) >= ts;
  96. }
  97.  
  98. int Solve(){
  99. int ans;
  100.  
  101. while(l <= r){
  102. Net.Clear();
  103. mid = l + (r - l) / ;
  104. if(check(mid)){
  105. ans = mid; r = mid - ;
  106. }
  107. else l = mid + ;
  108. }
  109.  
  110. return ans;
  111. }
  112.  
  113. int main(){
  114. int x, y, z;
  115.  
  116. scanf("%d%d%d", &ns, &ps, &ts);
  117. Net.n = ns;
  118. for(int i = ; i < ps; ++ i){
  119. scanf("%d%d%d", &x, &y, &z);
  120. E[i] = (Edge){x, y, z, };
  121. l = min(l, z); r = max(r, z);
  122. }
  123.  
  124. printf("%d\n", Solve());
  125. return ;
  126. }

POJ 2455

让人更加不能理解的是,为什么我换了上面的邻接表的形式,用STL容器来存邻接表就AC,用数组来存就T成狗。

下面是我狂T的代码,良心网友们给查查错误呗。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <algorithm>
  6. #include <queue>
  7.  
  8. using namespace std;
  9.  
  10. int ns, ps, ts, te;
  11. int l=0x3f3f3f3f, r, Mid;
  12.  
  13. struct Edge{
  14. int from, to, dt;
  15. }e[ + ];
  16.  
  17. struct Dinic{
  18. static const int maxn = + ;
  19. static const int maxm = + ;
  20. static const int oo = 0x3f3f3f3f;
  21.  
  22. int n,m,s,t;
  23. int tot;
  24. int first[maxn],next[maxm];
  25. int u[maxm],v[maxm],cap[maxm],flow[maxm];
  26. int cur[maxn],dis[maxn];
  27. bool vi[maxn];
  28.  
  29. Dinic(){tot=;memset(first,-,sizeof first);}
  30. void Clear(){tot = ;memset(first,-,sizeof first);}
  31. void Add(int from,int to,int cp,int flw){
  32. u[tot] = from;v[tot] = to;cap[tot] = cp;flow[tot] = ;
  33. next[tot] = first[u[tot]];
  34. first[u[tot]] = tot;
  35. ++ tot;
  36. }
  37. bool bfs(){
  38. memset(vi,false,sizeof vi);
  39. queue <int> q;
  40. dis[s] = ;vi[s] = true;
  41. q.push(s);
  42.  
  43. while(!q.empty()){
  44. int now = q.front();q.pop();
  45. for(int i = first[now];i != -;i = next[i]){
  46. if(!vi[v[i]] && cap[i] > flow[i]){
  47. vi[v[i]] = true;
  48. dis[v[i]] = dis[now] + ;
  49. q.push(v[i]);
  50. }
  51. }
  52. }
  53. return vi[t];
  54. }
  55. int dfs(int x,int a){
  56. if(x == t || a == ) return a;
  57. int flw=,f;
  58. int &i = cur[x];
  59. for(i = first[x];i != -;i = next[i]){
  60. if(dis[x] + == dis[v[i]] && (f = dfs(v[i],min(a,cap[i]-flow[i]))) > ){
  61. flow[i] += f;flow[i^] -= f;
  62. a -= f;flw += f;
  63. if(a == ) break;
  64. }
  65. }
  66. return flw;
  67. }
  68. int MaxFlow(int s,int t){
  69. this->s = s;this->t = t;
  70. int flw=;
  71. while(bfs()){
  72. memset(cur,,sizeof cur);
  73. flw += dfs(s,oo);
  74. }
  75. return flw;
  76. }
  77. }Net;
  78.  
  79. bool check(int mid){
  80. Net.Clear();
  81. for(int i = ; i <= ps; ++ i){
  82. if(e[i].dt <= mid){
  83. Net.Add(e[i].from, e[i].to, , );
  84. Net.Add(e[i].to, e[i].from, , );
  85. }
  86. }
  87. return Net.MaxFlow(, Net.n) >= ts;
  88. }
  89. int Solve(){
  90. int ans;
  91. while(l <= r){
  92. Mid = l + (r - l) / ;
  93. if(check(Mid)){
  94. ans = Mid; r = Mid - ;
  95. }
  96. else l = Mid + ;
  97. }
  98. return ans;
  99. }
  100. int main(){
  101. int x, y, z;
  102. scanf("%d%d%d", &ns, &ps, &ts);
  103. Net.n = ns;te = ;
  104. for(int i = ; i <= ps; ++ i){
  105. scanf("%d%d%d", &x, &y, &z);
  106. ++ te;
  107. e[te].from = x;e[te].to = y;e[te].dt = z;
  108. l = min(l, z); r = max(z, r);
  109. }
  110. printf("%d\n", Solve());
  111. return ;
  112. }

POJ 2455 T 版

POJ 2455 Secret Milking Machine (二分 + 最大流)的更多相关文章

  1. poj 2455 Secret Milking Machine 二分+最大流 sap

    题目:p条路,连接n个节点,现在需要从节点1到节点n,不重复走过一条路且走t次,最小化这t次中连接两个节点最长的那条路的值. 分析:二分答案,对于<=二分的值的边建边,跑一次最大流即可. #in ...

  2. POJ 2455 Secret Milking Machine(最大流+二分)

    Description Farmer John is constructing a new milking machine and wishes to keep it secret as long a ...

  3. POJ 2455 Secret Milking Machine (二分+无向图最大流)

    [题意]n个点的一个无向图,在保证存在T条从1到n的不重复路径(任意一条边都不能重复)的前提下,要使得这t条路上经过的最长路径最短. 之所以把"经过的最长路径最短"划个重点是因为前 ...

  4. POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)

    Secret Milking Machine Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9658   Accepted: ...

  5. POJ 2455 Secret Milking Machine 【二分】+【最大流】

    <题目链接> 题目大意: FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l.现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路段不能与先前的路径重复,问这些路径中 ...

  6. POJ 2455 - Secret Milking Machine

    原题地址:http://poj.org/problem?id=2455 题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的 ...

  7. POJ 2112 Optimal Milking(二分+最大流)

    http://poj.org/problem?id=2112 题意: 现在有K台挤奶器和C头奶牛,奶牛和挤奶器之间有距离,每台挤奶器每天最多为M头奶挤奶,现在要安排路程,使得C头奶牛所走的路程中的最大 ...

  8. POJ - 2112 Optimal Milking (dijkstra + 二分 + 最大流Dinic)

    (点击此处查看原题) 题目分析 题意:在一个农场中有k台挤奶器和c只奶牛,每个挤奶器最多只能为m只奶牛挤奶,每个挤奶器和奶牛都视为一个点,将编号1~k记为挤奶器的位置,编号k+1~k+c记为奶牛的位置 ...

  9. POJ 2112 Optimal Milking (Floyd+二分+最大流)

    [题意]有K台挤奶机,C头奶牛,在奶牛和机器间有一组长度不同的路,每台机器每天最多能为M头奶牛挤奶.现在要寻找一个方案,安排每头奶牛到某台机器挤奶,使得C头奶牛中走过的路径长度的和的最大值最小. 挺好 ...

随机推荐

  1. xampp集成安装的mysql修改密码(Window)

    把mysql安装目录bin文件夹加入环境变量 path:mysqlPath\bin; 或者进入mysql安装目录bin文件夹下,按住shift键盘鼠标右击进入命令行 键入命令 mysqladmin - ...

  2. vector-2

    assign函数 语法: void assign( input_iterator start, input_iterator end ); void assign( size_type num, co ...

  3. 锋利jQuery 学习整理之 第六章 jQuery 与Ajax 的应用

    1.Ajax 的XMLHttpRequest 对象 XMLHttpRequest 是Ajax 的核心,它是Ajax 实现的关键---发送异步请求.接受响应及执行回调都是通过它来完成的.XMLHttpR ...

  4. linux 安装中文支持包及中文字符集配置

    由于某些原因系统安装时未安装中文支持,导致后续应用出现中文方块乱码现象,解决方法很简单,当然不是重装,只需以下三步即可搞定. 1.安装中文包: #yum -y groupinstall chinese ...

  5. php的一些小笔记-文件函数(1)

    ---恢复内容开始--- 与文件操作相关的函数有一部分可以和linux命令比较,但是我觉得可能还是linux上使用的比较频繁 如:chown,chmod,chgrp,rename,touch,link ...

  6. 升级10.11后使用CocoaPod出现-bash: pod: command not found 解决办法-备

    升级10.11后,运行pod命令出现: -bash: pod: command not found 解决办法: sudo gem install -n /usr/local/bin cocoapods ...

  7. Ueditor开发经验

    Ueditor是百度开发的一款免费使用的富文本编辑器. 先前就一直使用Ueditor,觉得功能挺多的,而且还给出了详细的文档,供二次开发. 但Ueditor已经出新的版本(和先前版本很不相同),网上很 ...

  8. dwz分页实现分析

    dwz给我们提供了一个很好的列表UI 我对它的分析后将页面分为四个部分 <form id="pagerForm" method="post" action ...

  9. Java BufferedWriter与BufferedReader操作文本文件

    /** * 采用字符流读取写入文本文件 */ public class FileUtil { /** * 写文件 * @param fileName * @param content */ publi ...

  10. Delphi中ShellExecute使用详解(详细解释10种显示状态)

    有三个API函数可以运行可执行文件WinExec.ShellExecute和CreateProcess.1.CreateProcess因为使用复杂,比较少用.2.WinExec主要运行EXE文件.如: ...