Secret Milking Machine
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8189   Accepted: 2485

Description

Farmer John is constructing a new milking machine and wishes to keep it secret as long as possible. He has hidden in it deep within his farm and needs to be able to get to the machine without being detected. He must make a total of T (1 <= T <= 200) trips to the machine during its construction. He has a secret tunnel that he uses only for the return trips.

The farm comprises N (2 <= N <= 200) landmarks (numbered 1..N) connected by P (1 <= P <= 40,000) bidirectional trails (numbered 1..P) and with a positive length that does not exceed 1,000,000. Multiple trails might join a pair of landmarks.

To minimize his chances of detection, FJ knows he cannot use any trail on the farm more than once and that he should try to use the shortest trails.

Help FJ get from the barn (landmark 1) to the secret milking machine (landmark N) a total of T times. Find the minimum possible length of the longest single trail that he will have to use, subject to the constraint that he use no trail more than once. (Note well: The goal is to minimize the length of the longest trail, not the sum of the trail lengths.)

It is guaranteed that FJ can make all T trips without reusing a trail.

Input

* Line 1: Three space-separated integers: N, P, and T

* Lines 2..P+1: Line i+1 contains three space-separated integers, A_i, B_i, and L_i, indicating that a trail connects landmark A_i to landmark B_i with length L_i.

Output

* Line 1: A single integer that is the minimum possible length of the longest segment of Farmer John's route.

Sample Input

7 9 2
1 2 2
2 3 5
3 7 5
1 4 1
4 3 1
4 5 7
5 7 1
1 6 3
6 7 3

Sample Output

5

Hint

Farmer John can travel trails 1 - 2 - 3 - 7 and 1 - 6 - 7. None of the trails travelled exceeds 5 units in length. It is impossible for Farmer John to travel from 1 to 7 twice without using at least one trail of length 5.

Huge input data,scanf is recommended.

Source

USACO 2005 February Gold

题意:

题意:FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l。现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路不能与先前的路径重复,问这些路径中的最长路的最小是多少。

思路:二分答案+网络流判定。

二分枚举最大边权,重新建图,只保存权不超过最大边权的边。即如果边的长度小于等于我们规定的最大边权 则添加这条边 权值为1, 否则标记为0 

然后在网络中起点终点间的容量是原图中的路径数,判断最大流是否>=T

只需要对模板就行修改下 之后二分即可   只需要修改添加边的地方  因为本题是双向边 所以添加的边以及其反方向边 都应该权值为cw

#include <stdio.h>
#include <string.h>
#define VM 222
#define EM 81111*2
#define inf 0x3f3f3f3f
struct Edge
{
int frm,to,cap,next;
}edge[EM]; int head[VM],dep[VM],ep,n; //dep为点的层次
void addedge (int cu,int cv,int cw) //第一条边下标必须为偶数
{
edge[ep].frm = cu;
edge[ep].to = cv;
edge[ep].cap = cw;
edge[ep].next = head[cu];
head[cu] = ep;
ep ++;
edge[ep].frm = cv;
edge[ep].to = cu;
edge[ep].cap = cw;
edge[ep].next = head[cv];
head[cv] = ep;
ep ++;
} int BFS (int src,int des) //求出层次图
{
int que[VM],i,front = 0,rear = 0;
memset (dep,-1,sizeof(dep));
que[rear++] = src;
dep[src] = 0;
while (front != rear)
{
int u = que[front++];
front = front%VM;
for (i = head[u];i != -1;i = edge[i].next)
{
int v = edge[i].to;
if (edge[i].cap > 0&&dep[v] == -1) //容量大于0&&未在dep中
{
dep[v] = dep[u] + 1; //建立层次图
que[rear ++] = v;
rear = rear % VM;
if (v == des) //找到汇点 返回
return 1;
}
}
}
return 0;
}
int dinic (int src,int des)
{
int i,res = 0,top;
int stack[VM]; //stack为栈,存储当前增广路
int cur[VM]; //存储当前点的后继 跟head是一样的
while (BFS(src,des)) //if BFS找到增广路
{
memcpy (cur,head,sizeof (head));
int u = src; //u为当前结点
top = 0;
while (1)
{
if (u == des) //增广路已全部进栈
{
int min = inf,loc ;
for (i = 0;i < top;i ++) //找最小的增广跟并loc记录其在stack中位置
if (min > edge[stack[i]].cap) //以便退回该边继续DFS
{
min = edge[stack[i]].cap;
loc = i;
}
for (i = 0;i < top;i ++) //偶数^1 相当加1 奇数^1相当减1 当正向边 = 0&&路径不合适时,正加负减
{ //偶数是正向边,奇数是负向边,边从0开始
edge[stack[i]].cap -= min;
edge[stack[i]^1].cap += min;
} //将增广路中的所有边修改
res += min;
top = loc;
u = edge[stack[top]].frm; //当前结点修改为最小边的起点
}
for (i = cur[u];i != -1;cur[u] = i = edge[i].next) //找到当前结点对应的下一条边
if (edge[i].cap != 0&&dep[u] + 1 == dep[edge[i].to])//不满足条件时,修改cur值(去掉不合适的占)eg:1-->2 1-->3 1-->4 有边 但只有
break; // 1-->4 这条边满足条件 就把1到2、3的边给去掉
if (cur[u] != -1) //当前结点的下一条边存在
{
stack[top ++] = cur[u]; //把该边放入栈中
u = edge[cur[u]].to; //再从下个点开始找
}
else
{
if (top == 0) //当前结点无未遍历的下一条边且栈空,DFS找不到下一条增广路
break;
dep[u] = -1; //当前结点不在增广路中,剔除该点
u = edge[stack[--top]].frm; //退栈 回朔,继续查找
}
}
}
return res;
}
struct IN
{
int x,y,c;
}q[EM];
int sovle(int mid,int src,int des,int m,int k)
{
ep = 0;
memset (head,-1,sizeof(head));
for(int i=0;i<m;i++)
{
if(q[i].c<=mid)
addedge(q[i].x,q[i].y,1);
// addedge(q[i].y,q[i].x,1); }
if(dinic (src,des)>=k) return 1;
return 0;
}
int main ()
{
int n,m,v1,v2,w,k,i;
int src,des;
while (scanf ("%d %d %d",&n,&m,&k)!=EOF)
{
// ep = 0;
src=1;des=n;
// memset (head,-1,sizeof(head));
for(i=0;i<m;i++)
{
scanf("%d %d %d",&v1,&v2,&w);
q[i].x=v1;q[i].y=v2;q[i].c=w;
}
int left,right,mid,ans=-1;
left=0;right=1000000;
while(left<=right)
{
mid=(left+right)/2;
if(sovle(mid,src,des,m,k))
{
ans=mid;
right=mid-1;
}
else left=mid+1;
}
printf ("%d\n",ans);
}
return 0;
}

Sap 算法

#include <stdio.h>
#include <string.h>
#define VM 222
#define EM 81111*2
#define inf 0x3f3f3f3f struct Edge
{
int to, frm, nxt, cap;
}edge[EM]; int head[VM], ep, n, src, des;
int dep[VM], gap[VM]; //gap[x]=y:说明残留网络中dep[i]=x的个数为y void addedge(int u, int v, int c)
{
edge[ep].frm = u;
edge[ep].to = v;
edge[ep].cap = c;
edge[ep].nxt = head[u];
head[u] = ep++;
edge[ep].frm = v;
edge[ep].to = u;
edge[ep].cap = 0;
edge[ep].nxt = head[v];
head[v] = ep++;
} void BFS()
{
memset(dep, -1, sizeof(dep));
memset(gap, 0, sizeof(gap));
gap[0] = 1; //说明此时有1个dep[i] = 0
int que[VM], front = 0, rear = 0;
dep[des] = 0;
que[rear++] = des;
int u, v;
while (front != rear)
{
u = que[front++];
front = front%VM;
for (int i=head[u]; i!=-1; i=edge[i].nxt)
{
v = edge[i].to;
if (edge[i].cap != 0 || dep[v] != -1)
continue;
que[rear++] = v;
rear = rear % VM;
++gap[dep[v] = dep[u] + 1]; //求出各层次的数量
}
}
} int Sap()
{
int res = 0;
BFS();
int cur[VM];
int stack[VM], top = 0;
memcpy(cur, head, sizeof(head));
int u = src, i;
while (dep[src] < n)
{
if (u == des)
{
int temp = inf, inser = n;
for (i=0; i!=top; ++i)
if (temp > edge[stack[i]].cap)
{
temp = edge[stack[i]].cap;
inser = i;
}
for (i=0; i!=top; ++i)
{
edge[stack[i]].cap -= temp;
edge[stack[i]^1].cap += temp;
}
res += temp;
top = inser;
u = edge[stack[top]].frm;
} if (dep[u] != 0 && gap[dep[u] -1] == 0)//出现断层,无增广路
break;
for (i = cur[u]; i != -1; i = edge[i].nxt)//遍历与u相连的未遍历结点
if (dep[edge[i].to] != -1)
if (edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1) //层序关系, 找到允许
break; if (i != -1)//找到允许弧
{
cur[u] = i;
stack[top++] = i;//加入路径栈
u = edge[i].to;//查找下一个结点
}
else //无允许的路径,修改标号 当前点的标号比与之相连的点中最小的多1
{
int min = n;
for (i = head[u]; i != -1; i = edge[i].nxt) //找到与u相连的v中dep[v]最小的点
{
if (edge[i].cap == 0)
continue;
if (min > dep[edge[i].to])
{
min = dep[edge[i].to];
cur[u] = i; //最小标号就是最新的允许弧
}
}
--gap[dep[u]]; //dep[u] 的个数变化了 所以修改gap
++gap[dep[u] = min + 1]; //将dep[u]设为min(dep[v]) + 1, 同时修改相应的gap[]
if (u != src) //该点非源点&&以u开始的允许弧不存在,退点
u = edge[stack[--top]].frm;
}
}
return res;
} struct IN
{
int x,y,c;
}q[EM];
int sovle(int mid,int m,int k)
{
//printf("jin\n");
ep = 0;
memset (head,-1,sizeof(head));
for(int i=0;i<m;i++)
{
if(q[i].c<=mid)
{
addedge(q[i].x,q[i].y,1);
addedge(q[i].y,q[i].x,1);//不知道为什么 sap需要添加2次 相反边
}
}
if(Sap()>=k) return 1;
return 0;
}
int main ()
{
int m,v1,v2,w,k,i;
while (scanf ("%d %d %d",&n,&m,&k)!=EOF)
{
src=1;des=n;
for(i=0;i<m;i++)
{
scanf("%d %d %d",&v1,&v2,&w);
q[i].x=v1;q[i].y=v2;q[i].c=w;
}
int left,right,mid,ans=-1;
left=0;right=1000000;
while(left<=right)
{
mid=(left+right)/2;
if(sovle(mid,m,k))
{
ans=mid;
right=mid-1;
}
else left=mid+1;
}
printf ("%d\n",ans);
}
return 0;
}

POJ 2455 网络流 基础题 二分+网络流 dicnic 以及 sap算法的更多相关文章

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

    题目大意: 给出一张无向图,找出T条从1..N的路径,互不重复,求走过的所有边中的最大值最小是多少. 算法讨论: 首先最大值最小就提醒我们用二分,每次二分一个最大值,然后重新构图,把那些边权符合要求的 ...

  2. cogs 728. [网络流24题] 最小路径覆盖问题 匈牙利算法

    728. [网络流24题] 最小路径覆盖问题 ★★★☆   输入文件:path3.in   输出文件:path3.out   评测插件时间限制:1 s   内存限制:128 MB 算法实现题8-3 最 ...

  3. cogs 14. [网络流24题] 搭配飞行员 二分图最大匹配 匈牙利算法

    14. [网络流24题] 搭配飞行员 ★★   输入文件:flyer.in   输出文件:flyer.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述]     飞行大队有 ...

  4. POJ 2391 Ombrophobic Bovines【二分 网络流】

    题目大意:F个草场,P条道路(无向),每个草场初始有几头牛,还有庇护所,庇护所有个容量,每条道路走完都有时间,问所有奶牛都到庇护所最大时间最小是多少? 思路:和POJ2112一样的思路,二分以后构建网 ...

  5. POJ 2455Secret Milking Machine(二分+网络流之最大流)

    题目地址:POJ2455 手残真浪费时间啊..又拖到了今天才找出了错误..每晚两道题不知不觉又变回了每晚一道题...sad.. 第一次在isap中忘记调用bfs,第二次则是遍历的时候竟然是从1開始遍历 ...

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

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

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

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

  8. 2-sat基础题 uvalive 3211

    蓝书325页的基础题 二分+2-sat //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using n ...

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

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

随机推荐

  1. OD调试篇1—Hello

    OD调试篇1—Hello 要求:通过OD将程序的标题“I love fishc.com”改为“I love you” 一.找到程序的标题“I love fishc.com” 1.把程序拖到OD运行出现 ...

  2. CoffeeScript 入门笔记

    写在前面: 被英文版指南坑了...闹了很久才明白.coffee怎么用.安装前需要有稳定版 Node.js, 和 npm (Node Package Manager). 借助 npm 可以安装 Coff ...

  3. 复制virtualenv环境到其他服务器环境配置的方法

    要在n多服务器端部署python的应用,虽然python本身是跨平台的,当时好多第三方的扩展却不一定都能做到各个版本兼容,即便是都是linux,在redhat系列和ubuntu系列之间来回导也是个很让 ...

  4. MVC项目中如何判断用户是在用什么设备进行访问

    使用UAParser在C#MVC项目中如何判断用户是在用什么设备进行访问(手机,平板还是普通的电脑) 现在我们开发的很多web应用都要支持手机等移动设备.为了让手机用户能有更加好的用户体验,我们经常为 ...

  5. 利用Adapter对象将数据填充到DataTable(或DataSet)的例子

    前: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DataAdapter ...

  6. poj3308Paratroopers(最小割)

    题目请戳这里 题目大意:给一个n*m的矩阵,给一些点(ri,ci)表示该点在第ri行第ci列.现在要覆盖所有的点,已知覆盖第i行代价为Ri,覆盖第j列代价为Cj.总代价是累乘的,求最小总代价能覆盖所有 ...

  7. 宣布正式发布 Biz Talk Services、Azure Active Directory 和 Traffic Manager, 同时发布 Azure Active Directory 高级版预览

    除经济优势之外,云计算还在可转化为竞争优势的应用程序开发方面提供了更大的灵活性.我们很高兴看到每天创建的新 Windows Azure 订阅超过 1000 个,更令人兴奋的是,有一半客户使用价值更高的 ...

  8. poj 1979 Red and Black(dfs)

    题目链接:http://poj.org/problem?id=1979 思路分析:使用DFS解决,与迷宫问题相似:迷宫由于搜索方向只往左或右一个方向,往上或下一个方向,不会出现重复搜索: 在该问题中往 ...

  9. LA-3135 - Argus(优先队列)

    3135 - Argus A data stream is a real-time, continuous, ordered sequence of items. Some examples incl ...

  10. iOS7支持九宫格

    Beta4支持九宫格 还没试,等最终版把,现在的有很多bug还比较费电 看网上有人说虽然终于出来了但是还是不如百度搜狗等输入法方便 前几个月在weiphone上还有人问支不支持结果回帖的都说没戏 这算 ...