洛谷P1401 城市
2018-03-12 22:52
281 查看
题目描述
N(2<=n<=200)个城市,M(1<=m<=40000)条无向边,你要找T(1<=T<=200)条从城市1到城市N的路,使得最长的边的长度最小,边不能重复用。输入输出格式
输入格式:第1行三个整数N,M,T用空格隔开。第2行到P+1行,每行包括三个整数Ai,Bi,Li表示城市Ai到城市Bi之间有一条长度为Li的道路。输出格式:输出只有一行,包含一个整数,即经过的这些道路中最长的路的最小长度。
输入输出样例
输入样例#1: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输出样例#1:
5
二分答案+网络流。。。
一开始的思路是 spfa 记录最短路径,一条一条删边。
但是样例把 T 改为3 就炸了。。。
又看到 最长路最小——这TM不是二分答案么???
于是 二分答案+dinic。。。
把用过的边打上标记,没用过的边若流量小于二分的mid,设为0,否则设为1。
注:双向边。。。
附代码:#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#define MAXN 210
#define MAXM 40010
#define MAX 999999999
using namespace std;
int n,m,k,s,t,c=2;
int head[MAXN],deep[MAXN];
struct node{
int next,to,w;
bool vis;
}a[MAXM<<2],b[MAXM<<2];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void add(int u,int v,int w){
a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
a[c].to=u;a[c].w=0;a[c].next=head[v];head[v]=c++;
}
void reset(int x){
for(int i=2;i<c;i++){
if(a[i].w==0||a[i].w<=x||a[i].w==MAX)a[i].vis=true;
else a[i].vis=false;
b[i]=a[i];
if(a[i].w!=0&&a[i].w!=MAX)b[i].w=1;
}
}
bool bfs(){
int u,v;
queue<int> q;
for(int i=0;i<=n+2;i++)deep[i]=0;
deep[s]=1;
q.push(s);
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u];i;i=b[i].next){
v=b[i].to;
if(b[i].vis&&b[i].w&&!deep[v]){
deep[v]=deep[u]+1;
if(v==t)return true;
q.push(v);
}
}
}
return false;
}
int dfs(int x,int limit){
if(x==t)return limit;
int v,cost=0,sum;
for(int i=head[x];i;i=b[i].next){
v=b[i].to;
if(b[i].vis&&b[i].w&&deep[v]==deep[x]+1){
sum=dfs(v,min(limit-cost,b[i].w));
if(sum>0){
b[i].w-=sum;
b[i^1].w+=sum;
cost+=sum;
if(cost==limit)break;
}
else deep[v]=-1;
}
}
return cost;
}
bool check(int x){
int ans=0;
reset(x);
while(bfs())ans+=dfs(s,MAX);
if(ans>=k)return true;
return false;
}
void init(){
int u,v,w,l,r=0,mid,ans=0;
n=read();m=read();k=read();
s=n+1;t=n+2;
for(int i=1;i<=m;i++){
u=read();v=read();w=read();
r=max(r,w);
add(u,v,w);add(v,u,w);
}
add(s,1,MAX);add(n,t,MAX);
while(l<=r){
mid=l+r>>1;
if(check(mid)){
ans=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%d\n",ans);
}
int main(){
init();
return 0;
}
相关文章推荐
- 洛谷 P1401 城市(二分+网络流)
- AC日记——城市 洛谷 P1401
- P1401 城市(30分,正解网络流)
- 洛谷3761,TJOI2017城市
- BZOJ4890 & 洛谷3761:[TJOI2017]城市——题解
- 洛谷 P1453 城市环路
- 洛谷 模拟城市2.0
- DeepStream: 新一代智能城市视频分析
- 构建省份城市级联
- 洛谷 P1270 “访问”美术馆
- BZOJ1012: [JSOI2008]最大数maxnumber(洛谷P1198)
- JS+XML 实现 省份和城市之间的联动
- 洛谷 https://www.luogu.org/problem/show?pid=T574
- UPCOJ-4148 - 洛谷P2566 - 围豆豆 - 状压spfa
- ASP自动识别IP,并跳转到来访问者所在的城市
- 银河英雄传说 洛谷1196 并查集
- 洛谷——最小生成树模板
- 中国50个城市在一个班级里的职务
- 银河英雄传说 洛谷1196 并查集
- 洛谷 P1242 新汉诺塔