POJ 2455 - Secret Milking Machine
原题地址:http://poj.org/problem?id=2455
题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的边的长度最短。两点之间允许有重边
数据范围:2 <= N <= 200, 1 <= P <= 40,000,1 <= T <= 200,1 <= 每条路的长度L <= 1,000,000
题目分析:
看到“最大值最小”的第一反应就是二分最大长度k,满足T条通路没有公共边的第一反应就是将每条边的容量赋为1然后跑一遍最大流。这样算法就出来了:读入并建图,二分最大长度k,将所有长度小于等于 k 的边的容量设为1, 大于 k 的边容量设为0,然后以1为源点,n为汇点做一遍最大流,如果满足最大流大于等于T,则合要求继续二分,直至找出答案。
一开始在双向边建图的时候有点犹豫。毕竟网络流要求每条边必须要有反向边。最开始的想法是将每条双向边都拆成两条单向边,对每条单向边都建立一条长度为无穷大的反向边(无穷大是为了保证二分时赋初始容量都将它们为0),但是后来证明这种想法是错误的:因为题目要求每条边只能走一次,但是按我的想法每条边可以正向走一次,反向走一次,加上题目中允许有重边,就使情况变得更加复杂。后来我发现网络流的反向边不一定要初始容量为0——就算我将这一条双向边的两个方向按照网络流的一对反向边来建立,初始容量都允许为1,无论正着流还是反着流这条边所能允许的总容量必然只有0或1……然后就想通了(希望能给这里想不太清楚的同学们一点帮助)
然后这道题TLE到死……经过hockey指点才发现是我Dinic 写残了,应该到不能流的时候就退出但是我没有……改掉这一点之后,我加上当前弧优化的Dinic还是可以600+MS勉强AC的
PS:网上有些人说重新建立源点和汇点,并连接一条从源点到1的容量为T的边,其实丝毫没有必要,直接以1为源点是可以的
//date 20140118
#include <cstdio>
#include <cstring> const int maxn = ;
const int maxm = ;
const int INF = 0x7FFFFFFF; inline int getint()
{
int ans(); char w = getchar();
while('' > w || w > '')w = getchar();
while('' <= w && w <= '')
{
ans = ans * + w - '';
w = getchar();
}
return ans;
} inline int min(int a, int b){return a < b ? a : b;}
inline int max(int a, int b){return a > b ? a : b;} int n, m, T;
int s, t;
struct edge
{
int v, w, c, next;
}E[maxm];
int a[maxn];
int now[maxn];
int nedge;
int lab[maxn]; inline void add(int u, int v, int w, int c)
{
E[++nedge].v = v;
E[nedge].c = c;
E[nedge].w = w;
E[nedge].next = a[u];
a[u] = nedge;
} int maxl, minl; inline int label()
{
static int q[maxn];
int l = , r = ;
memset(lab, 0xFF, sizeof lab);
q[] = s; lab[s] = ;
while(l < r)
{
int x = q[++l];
for(int i = a[x]; i; i = E[i].next)
if(E[i].c == && lab[E[i].v] == -)
{
lab[E[i].v] = lab[x] + ;
q[++r] = E[i].v;
}
}
return lab[t] != -;
} int Dinic(int v, int f)
{
if(v == t)return f;
int res = , w;
for(int i = now[v]; i; i = now[v] = E[i].next)
if((E[i].c == ) && (f > ) && (lab[v] + == lab[E[i].v]) && (w = Dinic(E[i].v, min(f, E[i].c))))
{
E[i].c -= w;
E[i ^ ].c += w;
f -= w;
res += w;
if(f == )break;
}
if(res == )lab[v] = -;
return res;
} inline int max_flow()
{
int ans = ;
while(label())
{
for(int i = s; i <= t; ++i)now[i] = a[i];
ans += Dinic(s, INF);
}
return ans;
} inline bool check(int k)
{
for(int i = ; i <= nedge; i += )
if(E[i].w <= k)E[i].c = E[i ^ ].c = ; else E[i].c = E[i ^ ].c = ;
int ans = max_flow();
//printf("%d\n", ans);
return ans >= T;
} inline int solve(int l, int r)
{
int mid;
while(l < r)
{
mid = (l + r) >> ;
if(check(mid))r = mid;
else l = mid + ;
}
return l;
} int main()
{
n = getint(); m = getint(); T = getint();
nedge = ; maxl = ; minl = INF;
s = ; t = n;
int x, y, z;
for(int i = ; i <= m; ++i)
{
x = getint(); y = getint(); z = getint();
add(x, y, z, );
add(y, x, z, );
maxl = max(maxl, z);
minl = min(minl, z);
}
int ans = solve(minl, maxl);
printf("%d\n", ans);
return ;
}
小结:建图还是需要多加思考多加练习,代码模板也是需要不断完善的,加油~
POJ 2455 - Secret Milking Machine的更多相关文章
- POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9658 Accepted: ...
- 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 【二分】+【最大流】
<题目链接> 题目大意: FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l.现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路段不能与先前的路径重复,问这些路径中 ...
- POJ2455 Secret Milking Machine
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12324 Accepted ...
- 【bzoj1733】[Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 二分+网络流最大流
题目描述 Farmer John is constructing a new milking machine and wishes to keep it secret as long as possi ...
- [bzoj1733][Usaco2005 feb]Secret Milking Machine 神秘的挤奶机_网络流
[Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 题目大意:约翰正在制造一台新型的挤奶机,但他不希望别人知道.他希望尽可能久地隐藏这个秘密.他把挤奶机藏在他的农 ...
随机推荐
- Understand User's Intent from Speech and Text
http://research.microsoft.com/en-us/projects/IntentUnderstanding/ Understanding what users like to d ...
- 解决方法:java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
hibernate4.3版本 报错: 把实体注解的声明方式修改一下解决,如: 将 @Entity@Table(name=”table_name”)改为@Entity(name=”table_name” ...
- MyEclipse2015破解版_MyEclipse 2015 stable 2.0 稳定版 破解日志
前言:在MyEclipse 2015 Stable 1.0下载安装破解日志(http://www.cnblogs.com/wql025/p/5161979.html)一文中,笔者主要讲述了该版本的破解 ...
- 【Unity--Apwork框架】AOP编程--拦截,用于缓存和异常处理(Unity框架的拦截注入-Interception)
第一步:定义拦截行为:CachingBehavior 和 ExceptionLoggingBehavior 他们都继承接口:IInterceptionBehavior (程序集 Microsoft.P ...
- 消除SDK更新时的“https://dl-ssl.google.com refused”异常
原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“https://dl-ssl.google.com ref ...
- hadoop浅尝 第一个hadoop程序
hadoop编程程序员需要完成三个类. map类,reduce类和主类. map和reduce类自然是分别完成map和reduce.而主类则负责对这两个类设置job.完成这三个类之后,我们生成一个ja ...
- REST_FRAMEWORK加深记忆-三种CLASS VIEW的进化史
一层一层的封装,又能到底层,就会有全局感啦... from rest_framework import status from rest_framework.response import Respo ...
- JDK与JRE
dos命令行中常见的命令: 1.dir:列出当前目录下的文件以及文件夹 2.md:创建目录(即文件夹) |-----C:\>md kkk(在C盘下创建了一个名为kkk的文件夹) 3.rd:删除目 ...
- QTP重要功能总结
以下为QTP最应掌握的.最常用的功能(以下仅提供菜单入口,其他还有很多入口,但功能都是一样的) 1.QTP上方菜单栏->Tools->Object Spy(对象探测器)----多个入口 功 ...
- JMeterPluginCMD命令行工具使用详解
MeterPluginCMD命令行工具生成png图片和csv统计文件 Jmeter是个纯java的开源的轻量级性能测试工具,功能强大.因为是轻量级的,与loadrunner相比,报告统计的相对较少.不 ...