[POJ3662] Telephone Lines
Posted HLX_Y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POJ3662] Telephone Lines相关的知识,希望对你有一定的参考价值。
题意:n个点,m条边,有k次机会免费走过一条边,最小化1~n的最大边权
题解:
spfa+二分
这题好像克我......,一开始写了个二分+spfa在洛谷上A了,poj上莫名wa掉
然后写另一种方法,读入读成点数了,一直没发现,wa了一万年......
二分最大边权
check把大于mid的边赋为1,小于等于mid的赋为0,spfa即可
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #define ll long long using namespace std; const int N = 1010; const int M = 100100; int n,m,k,e_num,L,T; int nxt[M*2],to[M*2],w[M*2],h[N],dis[N],b[M*2]; bool in[N]; queue<int> q; int gi() { int x=0,o=1; char ch=getchar(); while(ch!=‘-‘ && (ch<‘0‘ || ch>‘9‘)) ch=getchar(); if(ch==‘-‘) o=-1,ch=getchar(); while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return o*x; } void add(int x, int y, int z) { nxt[++e_num]=h[x],to[e_num]=y,w[e_num]=z,h[x]=e_num; } bool check(int mid) { for(int i=1; i<=e_num; i++) { if(w[i]>mid) b[i]=1; else b[i]=0; } memset(dis,0x7f,sizeof(dis)); dis[1]=0,in[1]=1,q.push(1); while(!q.empty()) { int u=q.front(); in[u]=0,q.pop(); for(int i=h[u]; i; i=nxt[i]) { int v=to[i]; if(dis[u]+b[i]<dis[v]) { dis[v]=dis[u]+b[i]; if(!in[v]) in[v]=1,q.push(v); } } } return dis[n]<=k; } int main() { int l,r,mid,ans; n=gi(),m=gi(),k=gi(); for(int i=1; i<=m; i++) { int x=gi(),y=gi(),z=gi(); add(x,y,z),add(y,x,z); L=max(L,z),T=min(T,z); } l=0,r=L,ans=L+1; while(l<=r) { mid=(l+r)>>1; if(check(mid)) ans=min(ans,mid),r=mid-1; else l=mid+1; } if(ans>L) puts("-1"); else printf("%d\n", ans); return 0; }
以上是关于[POJ3662] Telephone Lines的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3662 Telephone Lines (分层图)
POJ 3662 Telephone Lines (分层图做法)
poj 3662 Telephone Lines(最短路+二分)