题目大意:

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

算法讨论:

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

这题有许多注意的地方:

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

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

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

Codes:

 #include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue> using namespace std; struct Edge{
int from, to, cap, flow;
Edge(int _from = , int _to = , int _cap = , int _flow = ):
from(_from), to(_to), cap(_cap), flow(_flow) {}
}E[ + ]; struct Dinic{
static const int N = + ;
static const int M = + ;
static const int oo = 0x3f3f3f3f; int n, m, s, t;
vector <Edge> edges;
vector <int> G[N];
int dis[N], cur[N];
bool vi[N]; void Clear(){
for(int i = ; i <= n; ++ i) G[i].clear();
edges.clear();
} void Add(int from, int to, int cap, int flow){
edges.push_back((Edge){from, to, cap, });
edges.push_back((Edge){to, from, cap, });
int m = edges.size();
G[from].push_back(m - );
G[to].push_back(m - );
} bool bfs(){
for(int i = ; i <= n; ++ i) vi[i] = false;
dis[s] = ; vi[s] = true;
queue <int> q; q.push(s); while(!q.empty()){
int x = q.front(); q.pop();
for(int i = ; i < G[x].size(); ++ i){
Edge &e = edges[G[x][i]];
if(!vi[e.to] && e.cap > e.flow){
vi[e.to] = true;
dis[e.to] = dis[x] + ;
q.push(e.to);
}
}
}
return vi[t];
} int dfs(int x, int a){
if(x == t || a == ) return a;
int flw = , f;
for(int &i = cur[x]; i < G[x].size(); ++ i){
Edge &e = edges[G[x][i]];
if(dis[x] + == dis[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > ){
e.flow += f; edges[G[x][i]^].flow -= f;
a -= f; flw += f;
if(!a) break;
}
}
return flw;
} int Maxflow(int s, int t){
this->s = s;this-> t = t;
int flw = ;
while(bfs()){
memset(cur, , sizeof cur);
flw += dfs(s, oo);
}
return flw;
} }Net; int ns, ps, ts;
int l = 0x3f3f3f3f, r, mid; bool check(int mv){
for(int i = ; i < ps; ++ i){
if(E[i].cap <= mv){
Net.Add(E[i].from, E[i].to, , );
}
}
return Net.Maxflow(, Net.n) >= ts;
} int Solve(){
int ans; while(l <= r){
Net.Clear();
mid = l + (r - l) / ;
if(check(mid)){
ans = mid; r = mid - ;
}
else l = mid + ;
} return ans;
} int main(){
int x, y, z; scanf("%d%d%d", &ns, &ps, &ts);
Net.n = ns;
for(int i = ; i < ps; ++ i){
scanf("%d%d%d", &x, &y, &z);
E[i] = (Edge){x, y, z, };
l = min(l, z); r = max(r, z);
} printf("%d\n", Solve());
return ;
}

POJ 2455

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

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

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue> using namespace std; int ns, ps, ts, te;
int l=0x3f3f3f3f, r, Mid; struct Edge{
int from, to, dt;
}e[ + ]; struct Dinic{
static const int maxn = + ;
static const int maxm = + ;
static const int oo = 0x3f3f3f3f; int n,m,s,t;
int tot;
int first[maxn],next[maxm];
int u[maxm],v[maxm],cap[maxm],flow[maxm];
int cur[maxn],dis[maxn];
bool vi[maxn]; Dinic(){tot=;memset(first,-,sizeof first);}
void Clear(){tot = ;memset(first,-,sizeof first);}
void Add(int from,int to,int cp,int flw){
u[tot] = from;v[tot] = to;cap[tot] = cp;flow[tot] = ;
next[tot] = first[u[tot]];
first[u[tot]] = tot;
++ tot;
}
bool bfs(){
memset(vi,false,sizeof vi);
queue <int> q;
dis[s] = ;vi[s] = true;
q.push(s); while(!q.empty()){
int now = q.front();q.pop();
for(int i = first[now];i != -;i = next[i]){
if(!vi[v[i]] && cap[i] > flow[i]){
vi[v[i]] = true;
dis[v[i]] = dis[now] + ;
q.push(v[i]);
}
}
}
return vi[t];
}
int dfs(int x,int a){
if(x == t || a == ) return a;
int flw=,f;
int &i = cur[x];
for(i = first[x];i != -;i = next[i]){
if(dis[x] + == dis[v[i]] && (f = dfs(v[i],min(a,cap[i]-flow[i]))) > ){
flow[i] += f;flow[i^] -= f;
a -= f;flw += f;
if(a == ) break;
}
}
return flw;
}
int MaxFlow(int s,int t){
this->s = s;this->t = t;
int flw=;
while(bfs()){
memset(cur,,sizeof cur);
flw += dfs(s,oo);
}
return flw;
}
}Net; bool check(int mid){
Net.Clear();
for(int i = ; i <= ps; ++ i){
if(e[i].dt <= mid){
Net.Add(e[i].from, e[i].to, , );
Net.Add(e[i].to, e[i].from, , );
}
}
return Net.MaxFlow(, Net.n) >= ts;
}
int Solve(){
int ans;
while(l <= r){
Mid = l + (r - l) / ;
if(check(Mid)){
ans = Mid; r = Mid - ;
}
else l = Mid + ;
}
return ans;
}
int main(){
int x, y, z;
scanf("%d%d%d", &ns, &ps, &ts);
Net.n = ns;te = ;
for(int i = ; i <= ps; ++ i){
scanf("%d%d%d", &x, &y, &z);
++ te;
e[te].from = x;e[te].to = y;e[te].dt = z;
l = min(l, z); r = max(z, r);
}
printf("%d\n", Solve());
return ;
}

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. 利用java Base64 实现加密、解密

    Base64加密解密 package com.stone.util; import java.io.UnsupportedEncodingException; import sun.misc.*; p ...

  2. Jquery对选取到的元素显示指定的长度,对于的字符串用“...”显示

    $(function() { $(".video_name").each(function() { var s = $(this).text(); $()); }); }); fu ...

  3. 【5】说说Laravel5的blade模板

    首先看一下以前的程序 routes.php PagesController.php resources/views/pages/about.blade.php 现在我们来简单的使用一下blade模板的 ...

  4. 各邮箱服务器地址及端口<转>

    gmail(google.com) POP3服务器地址:pop.gmail.com(SSL启用端口:995) SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587) 21cn.c ...

  5. [HDU] 2094 产生冠军(拓扑排序+map)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2094 注意每组数据处理前,map要清空. #include<cstdio> #includ ...

  6. VC-关于VC++ 6.0的那些事儿

    Microsoft Visual C++,(简称Visual C++.MSVC.VC++或VC)微软公司的C++开发工具,具有集成开发环境,可提供编辑C语言,C++以及C++/CLI等编程语言.VC+ ...

  7. 05_Elasticsearch 单模式下API的增删改查操作

    05_Elasticsearch 单模式下API的增删改查操作 安装marvel 插件: zjtest7-redis:/usr/local/elasticsearch-2.3.4# bin/plugi ...

  8. Base64 加密之中文乱码

    ase64编码将二进制数据按照每三个字节转换成四个字节可读字符,编码后的字符长度大约为136.1%.字符范围为 A-Z  a-z  0-9  \  +.但编码后的字符串不太适合使用URL传输,中文加密 ...

  9. WEB打印插件Lodop

    Lodop.C-Lodop使用说明及样例   Lodop(标音:劳道谱,俗称:露肚皮)是专业WEB控件,用它既可裁剪输出页面内容,又可用程序代码直接实现 复杂打印.控件功能强大,却简单易用,所有调用如 ...

  10. HDU 5418 Victor and World (Floyd + 状态压缩DP)

    题目大意:从起点 1 开始走遍所有的点,回到起点 1 ,求出所走的最短长度. 思路:首先利用 Floyed 求出任意两点之间的最短距离 dis[i][j].求出任意两点之间的最短距离后,运用动态规划. ...