POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 9658 | Accepted: 2859 |
Description
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
* 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
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
Huge input data,scanf is recommended.
Source
题目大意:
FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l。如今要你找出从第1块地到第n块地的T条不同路径,每条路径上的路不能与先前的路径反复,问这些路径中的最长路的最小是多少。
解题思路:
二分+网络流。
解题代码:
代码一:DINIC算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std; const int INF=(1<<30);
const int maxn=210,maxm=201000; struct edge{
int u,v,f,next;
edge(int u0=0,int v0=0,int f0=0){
u=u0;v=v0;f=f0;
}
}e[maxm]; int src,sink,cnt,head[maxn]; void adde(int u,int v,int f){
e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].next=head[u],head[u]=cnt++;
e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].next=head[v],head[v]=cnt++;
} void init(){
cnt=0;
memset(head,-1,sizeof(head));
} queue <int> q;
bool visited[maxn];
int dist[maxn]; void bfs(){
memset(dist,0,sizeof(dist));
while(!q.empty()) q.pop();
visited[src]=true;
q.push(src);
while(!q.empty()){
int s=q.front();
q.pop();
for(int i=head[s];i!=-1;i=e[i].next){
int d=e[i].v;
if(e[i].f>0 && !visited[d]){
q.push(d);
dist[d]=dist[s]+1;
visited[d]=true;
}
}
}
} int dfs(int u,int delta){
if(u==sink) return delta;
else{
int ret=0;
for(int i=head[u];delta && i!=-1;i=e[i].next){
if(e[i].f>0 && dist[e[i].v]==dist[u]+1){
int d=dfs(e[i].v,min(e[i].f,delta));
e[i].f-=d;
e[i^1].f+=d;
delta-=d;
ret+=d;
}
}
if(!ret) dist[u]=-2;
return ret;
}
} int maxflow(){
int ret=0;
while(true){
memset(visited,false,sizeof(visited));
bfs();
if(!visited[sink]) return ret;
ret+=dfs(src,INF);
}
return ret;
} int n,m,num,maxr,minr;
vector <edge> vec; void input(){
maxr=0;
minr=INF;
src=1,sink=n;
vec.clear();
int u,v,w;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
vec.push_back(edge(u,v,w));
vec.push_back(edge(v,u,w));
if(w>maxr) maxr=w;
if(w<minr) minr=w;
}
} void build(int dis0){
init();
for(int i=0;i<vec.size();i++){
if(vec[i].f<=dis0){
adde(vec[i].u,vec[i].v,1);
}
}
} void solve(){
int l=minr,r=maxr;
while(l<r){
int mid=(l+r)/2;
build(mid);
if(maxflow()>=num) r=mid;
else l=mid+1;
}
printf("%d\n",r);
} int main(){
while(scanf("%d%d%d",&n,&m,&num)!=EOF){
input();
solve();
}
return 0;
}
代码二:sap算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; #define INF 2000000000
#define N 100010
typedef long long ll; const int maxn=210;
struct edge{
int u,v,next,cap;
edge(int u0=0,int v0=0,int f0=0){
u=u0;v=v0;cap=f0;
}
}e[210000]; int n,head[N],tol,top,st[N];
int src,des,dep[N],gap[N]; void adde(int u,int v,int c){
e[tol].u=u,e[tol].v=v,e[tol].next=head[u],e[tol].cap=c,head[u]=tol++;
e[tol].u=v,e[tol].v=u,e[tol].next=head[v],e[tol].cap=0,head[v]=tol++;
} void bfs(){//对于反边计算层次
for(int i=0;i<N;i++) dep[i]=N-1;
memset(gap,0,sizeof gap);
gap[0]=1,dep[des]=0;
int q[N],l=0,r=0,u,v;
q[r++]=des;
while(l!=r){
u=q[l++];
l=l%N;
for(int i=head[u];i!=-1;i=e[i].next){
v=e[i].v;
if(e[i].cap!=0||dep[v]!=N-1) continue;
q[r++]=v;
r=r%N;
++gap[dep[v]=dep[u]+1];
}
}
} int sap(){
bfs();
int u=src,s[N],top=0,res=0,ii;
int cur[N];
memcpy(cur,head,sizeof head);
while(dep[src]<n){
if(u==des){//求得一条增广路
int minf=INF,pos=n;
for(int i=0;i<top;i++){
if(minf>e[s[i]].cap){
minf=e[s[i]].cap;
pos=i;
}
}
for(int i=0;i<top;i++){
e[s[i]].cap-=minf;
e[s[i]^1].cap+=minf;
}
top=pos;
res+=minf;
u=e[s[top]].u;//优化1
}
if(dep[u]!=0&&gap[dep[u]-1]==0) break;//出现断层
ii=-1;
for(int i=cur[u];i!=-1;i=e[i].next){
if(dep[e[i].v]==N-1) continue;
if(e[i].cap!=0&&dep[u]==dep[e[i].v]+1){ii=i;break;}
}
if(ii!=-1){//有同意弧
cur[u]=ii;
s[top++]=ii;
u=e[ii].v;
}else{//不断回退找增光路
int mind=n;
for(int i=head[u];i!=-1;i=e[i].next){
if(e[i].cap==0) continue;
if(dep[e[i].v]<mind) mind=dep[e[i].v],cur[u]=i;
}
--gap[dep[u]];
++gap[dep[u]=mind+1];//优化2
if(u!=src) u=e[s[--top]].u;
}
}
return res;
} int m,num,maxr,minr;
vector <edge> vec; void input(){
maxr=0;
minr=INF;
vec.clear();
int u,v,w;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
vec.push_back(edge(u,v,w));
vec.push_back(edge(v,u,w));
if(w>maxr) maxr=w;
if(w<minr) minr=w;
}
} void build(int dis0){
tol=0;
memset(head,-1,sizeof head);
src=1,des=n,n;
int vsize=vec.size();
for(int i=0;i<vsize;i++){
if(vec[i].cap<=dis0) adde(vec[i].u,vec[i].v,1);
}
} void solve(){
int l=minr,r=maxr;
while(l<r){
int mid=(l+r)/2;
build(mid);
if(sap()>=num) r=mid;
else l=mid+1;
}
printf("%d\n",r);
} int main(){
while(scanf("%d%d%d",&n,&m,&num)!=EOF){
input();
solve();
}
return 0;
}
POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)的更多相关文章
- POJ 2455 Secret Milking Machine 【二分】+【最大流】
<题目链接> 题目大意: FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l.现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路段不能与先前的路径重复,问这些路径中 ...
- POJ 2455 Secret Milking Machine(最大流+二分)
Description Farmer John is constructing a new milking machine and wishes to keep it secret as long a ...
- POJ 2455 Secret Milking Machine (二分 + 最大流)
题目大意: 给出一张无向图,找出T条从1..N的路径,互不重复,求走过的所有边中的最大值最小是多少. 算法讨论: 首先最大值最小就提醒我们用二分,每次二分一个最大值,然后重新构图,把那些边权符合要求的 ...
- poj 2455 Secret Milking Machine 二分+最大流 sap
题目:p条路,连接n个节点,现在需要从节点1到节点n,不重复走过一条路且走t次,最小化这t次中连接两个节点最长的那条路的值. 分析:二分答案,对于<=二分的值的边建边,跑一次最大流即可. #in ...
- POJ 2455 Secret Milking Machine (二分+无向图最大流)
[题意]n个点的一个无向图,在保证存在T条从1到n的不重复路径(任意一条边都不能重复)的前提下,要使得这t条路上经过的最长路径最短. 之所以把"经过的最长路径最短"划个重点是因为前 ...
- POJ 2455 - Secret Milking Machine
原题地址:http://poj.org/problem?id=2455 题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的 ...
- POJ2455 Secret Milking Machine【二分,最大流】
题目大意:N个点P条边,令存在T条从1到N的路径,求路径上的边权的最大值最小为多少 思路:做了好多二分+最大流的题了,思路很好出 二分出最大边权后建图,跑dinic 问题是....这题是卡常数的好题! ...
- POJ 2455:Secret Milking Machine(二分+最大流)
http://poj.org/problem?id=2455 题意:给出n个点和m条无向路,每条路都有一个长度.从1点到n点要走t次两两互不重合的路.求出每条1->n的路中相邻两点最大值的最小值 ...
- POJ 2455Secret Milking Machine(二分+网络流之最大流)
题目地址:POJ2455 手残真浪费时间啊..又拖到了今天才找出了错误..每晚两道题不知不觉又变回了每晚一道题...sad.. 第一次在isap中忘记调用bfs,第二次则是遍历的时候竟然是从1開始遍历 ...
随机推荐
- Linux中ssh的免密码登陆
原理: Hadoop的各个节点要实时的进行各种通信的,ssh就是能让各个节点免密码的相互访问相互通信. 操作步骤: 这里用的加密方式是非对称的加密方式,具体的操作是: <1>执行命令ssh ...
- Linux下 保存 git账号密码
一.通过文件方式 1.在~/下, touch创建文件 .git-credentials, 用vim编辑此文件,输入内容格式: touch .git-credentials vim .git-crede ...
- IOS 学习笔记(7) 控件 分隔栏控件(UISegmentControl)的使用方法
分隔栏控件的系统默认式样一共有3种,分别是“普通式样”,"边框式样","条状式样" 分隔栏控件中有一个momentary属性,默认时NO.当开发者配置成YES时 ...
- DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间
dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文 ...
- 隐藏nginx 版本号信息(转)
为了安全,想将http请求响应头里的nginx版本号信息隐藏掉: 1. nginx配置文件里增加 server_tokens off; server_tokens作用域是http server loc ...
- Android 进程和线程模型
Android进程模型 在安装Android应用程序的时候,Android会为每个程序分配一个Linux用户ID,并设置相应的权限,这样其它应用程序就不能访问此应用程序所拥有的数据和资源了. 在 Li ...
- 关于GROUP BY的应用
前面收藏了别人的SQL语句操作,可是没有实战,也未知学的如何 正好今天有个事需要做一下 (sql server 2000) 三个表:stuInf,sType,sinInf分别为学生信息表,类型表,信息 ...
- Winter(bfs&&dfs)
1084 - Winter PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Winter is ...
- vi 替换命令“找不到模式”解决
在linux vi编辑工具中使用替换命令操作时,会出现明明有匹配查找模式的数据.却报"找不到模式"问题. 原因是vi s///替换操作缺省针对行,若要生效,则须要将光标移动到指定行 ...
- SQL执行效率总结
1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2000 目的: 查询 ...