POJ2455 Secret Milking Machine【二分,最大流】
题目大意:N个点P条边,令存在T条从1到N的路径,求路径上的边权的最大值最小为多少
思路:做了好多二分+最大流的题了,思路很好出 二分出最大边权后建图,跑dinic
问题是。。。。这题是卡常数的好题!!!!!
T了8发以后实在受不了,瞄了眼网上的程序,齐刷刷的邻接矩阵。。。。论邻接矩阵的优越性
但不信邪的我终于反复优化常数后邻接表A了
//TLE的程序
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#define maxn 200090
#define esp 0.001
#define inf 0x3f3f3f3f
using namespace std;
int head[300],next[maxn],point[maxn],now=0;
int flow[maxn],dist[300];
int tt,p,h=0,n;
struct T
{
int x;int y;int v;
}a[maxn];
void add(int x,int y,int v)
{
next[++now]=head[x];
head[x]=now;
point[now]=y;
flow[now]=v;
next[++now]=head[y];
head[y]=now;
point[now]=x;
flow[now]=0;
}
int bfs(int s,int t,int x)
{
queue<int>q;
q.push(s);
memset(dist,-1,sizeof(dist));
dist[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=next[i])
{
int k=point[i];
if(flow[i]!=0&&dist[k]==-1)
{
dist[k]=dist[u]+1;
q.push(k);
}
}
}
return dist[t]!=-1;
}
int dfs(int s,int d,int t,int x)
{
if(s==t)return d;
int res=0;
for(int i=head[s];i&&res<d;i=next[i])
{
int u=point[i];
if(flow[i]&&dist[u]==dist[s]+1)
{
int dd=dfs(u,min(flow[i],d-res),t,x);
if(dd)
{
flow[i]-=dd;
flow[((i-1)^1)+1]+=dd;
res+=dd;
}
}
}
if(res==0)dist[s]=-1;
return res;
}
int judge(int x,int s,int t)
{
int ans=0;
memset(head,0,sizeof(head));
now=0;
for(int i=1;i<=p;i++)if(a[i].v<=x)
{
add(a[i].x,a[i].y,1);
add(a[i].y,a[i].x,1);
}
add(s,1,tt);add(n,t,inf);
while(bfs(s,t,x))
{ans+=dfs(s,inf,t,x);}
if(ans>=tt)return 1;else return 0;
}
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
int x,y,v;
int l=0x3f3f3f3f,r=0,mid;
scanf("%d%d%d",&n,&p,&tt);
int s=n+10,t=n+12;
for(int i=1;i<=p;i++)
{
x=read();y=read();v=read();
a[i].x=x;a[i].y=y;a[i].v=v;
r=max(r,v);
l=min(l,v);
}
while(mid=(l+r)>>1,l<r)
{
if(judge(mid,s,t)==1)r=mid;else l=mid+1;
}
printf("%d\n",r);
return 0;
}
//AC的程序
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#define maxn 200090
#define esp 0.001
#define inf 0x3f3f3f3f
using namespace std;
int head[300],next[maxn],point[maxn],now=0;
int flow[maxn],dist[300];
int tt,p,h=0,n;
struct T
{
int x;int y;int v;
}a[maxn];
void add(int x,int y,int v)
{
next[++now]=head[x];
head[x]=now;
point[now]=y;
flow[now]=v;
next[++now]=head[y];
head[y]=now;
point[now]=x;
flow[now]=0;
}
int bfs(int s,int t,int x)
{
queue<int>q;
q.push(s);
memset(dist,-1,sizeof(dist));
dist[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=next[i])
{
int k=point[i];
if(flow[i]!=0&&dist[k]==-1)
{
dist[k]=dist[u]+1;
q.push(k);
}
}
}
return dist[t]!=-1;
}
int dfs(int s,int d,int t,int x)
{
if(s==t)return d;
int res=0;
for(int i=head[s];i&&res<d;i=next[i])
{
int u=point[i];
if(flow[i]&&dist[u]==dist[s]+1)
{
int dd=dfs(u,min(flow[i],d-res),t,x);
if(dd)
{
flow[i]-=dd;
flow[((i-1)^1)+1]+=dd;
res+=dd;
}
}
}
if(res==0)dist[s]=-1;
return res;
}
int judge(int x,int s,int t)
{
int ans=0;
memset(head,0,sizeof(head));
now=0;
for(int i=1;i<=p;i++)if(a[i].v<=x)
{
add(a[i].x,a[i].y,1);
add(a[i].y,a[i].x,1);
}
add(s,1,tt);add(n,t,inf);
while(bfs(s,t,x))
{ans+=dfs(s,inf,t,x);}
if(ans>=tt)return 1;else return 0;
}
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
int x,y,v;
int l=0x3f3f3f3f,r=0,mid;
scanf("%d%d%d",&n,&p,&tt);
int s=n+10,t=n+12;
for(int i=1;i<=p;i++)
{
x=read();y=read();v=read();
a[i].x=x;a[i].y=y;a[i].v=v;
r=max(r,v);
l=min(l,v);
}
while(mid=(l+r)>>1,l<r)
{
if(judge(mid,s,t)==1)r=mid;else l=mid+1;
}
printf("%d\n",r);
return 0;
}
做完也是醉了,不A不睡觉TUT
转载于:https://www.cnblogs.com/philippica/p/4127521.html
POJ2455 Secret Milking Machine【二分,最大流】相关推荐
- poj2455 Secret Milking Machine(二分答案+最大流)
二分答案,双向边网络流,反向边容量直接设为val即可.可以选择的边容量为1,跑最大流,看是否满流(是否存在K条路径). #include <cstdio> #include <cst ...
- poj 2455 Secret Milking Machine(二分枚举+最大流)
题意: 题意:FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l.现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路不能与先前的路径重复,问这些路径中的最长路的最小是多少. 思 ...
- POJ 2455 Secret Milking Machine 二分枚举 + 最大流
题目:http://poj.org/problem?id=2455 题意:给定一张无向图,有n个节点p条边,要求在图中从1到n找到t条路径,并且使这t条路径中的最长边最小,输出这个最小的最长边 思路: ...
- POJ 2455 Secret Milking Machine (二分+无向图最大流)
[题意]n个点的一个无向图,在保证存在T条从1到n的不重复路径(任意一条边都不能重复)的前提下,要使得这t条路上经过的最长路径最短. 之所以把"经过的最长路径最短"划个重点是因为前 ...
- POJ 2112 Optimal Milking(二分+最大流)
POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每一个机器能容纳m个奶牛.问全部奶牛都能挤上奶,那么走的距离最 ...
- BZOJ1733: [Usaco2005 feb]Secret Milking Machine 神秘的挤奶机
n<=200个点m<=40000条边无向图,求 t次走不经过同条边的路径从1到n的经过的边的最大值 的最小值. 最大值最小--二分,t次不重边路径--边权1的最大流. 1 #inc ...
- Secret Milking Machine POJ - 2455
点击打开链接 二分最大边 记为lim 不超过lim的边容量记为1 否则记为0 再抽象一个源点 从源点到1的容量为题目所给的t 然后以此建图 看是否满流 感觉网络流的抽象建图很关键 这道题看了别人的建图 ...
- POJ 2455 Secret Milking Machine
POJ_2455 每条路只走一次可以通过网络流来保证,而对于让最长的边最小可以通过二分枚举来搞定. #include<stdio.h> #include<string.h> # ...
- POJ3228二分最大流
题意: 有n个点,每个点有两个权值,金子数量还有仓库容量,金子可以存在自己的仓库里或者是别的仓库里,仓库和仓库之间有距离,问所有金子都必须存到库里最大距离的最小是多少? 思路: ...
最新文章
- jQuery中FormData的使用
- 汽车自动泊车APA简介
- seaborn系列 (13) | 点图pointplot()
- android-ndk-r15c libncurses.so.5
- Java线程之join
- 使用tensorflow训练数据时遇到的问题总结
- java8生成jsp页面内容组装到jsp中_JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...
- oracle12c 新增维护时间窗口,ORACLE 12C新特性-自动维护全局索引 | 信春哥,系统稳,闭眼上线不回滚!...
- Spring Boot 使用 Dom4j XStream 操作 Xml
- java字体除了宋体,为什么许多中文网站的主要字体仍然采用宋体而不是微软雅黑?...
- BLUE引擎M2运行几天后就不可以施放合击技能的方法
- win10 摄像头启动不了
- 第三届火焰杯软件测试初赛题目
- 逆幂律模型_思维模型18 - 幂律分布是什么?
- ServU配置网络盘
- 黑马程序员--IDEA版本2018Java基础班+就业班大牛编程吧
- 阿里 P9 开源分享内部 Java 核心开发手册(2022 版)覆盖 P5 到 P8
- 《电脑音乐制作实战指南:伴奏、录歌、MTV全攻略》——2.5 实战WAV、MP3等音频歌曲的原唱消除...
- matlab中的diag函数
- java cache定时过期,本地缓存高性能之王Caffeine
热门文章
- 【深度学习】面向医学图像的病灶分割调研(一)
- 【Linux入门到精通系列讲解】一些基础问题
- python【数据结构与算法】快速幂and矩阵快速幂取模(看不懂你来打我)
- matlab zeros(12 1),Matlab中 函数zeroS(1,8) 代表什么意思??
- python大一知识点_python知识点复习
- java万年历计算法定节假日,java获取中国节假日
- 宁波网络推广浅析网站在优化关键词需注意哪些事项?
- 网站推广专员浅析网站推广对企业运营优化的重要性不可忽视
- 传统网站与营销型网站区别盘比
- docker新增目录映射_开发也需了解的运维知识之Docker