[Usaco2007 Jan]Telephone Lines架设电话线
Posted zincsabian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Usaco2007 Jan]Telephone Lines架设电话线相关的知识,希望对你有一定的参考价值。
好题!...(躺)
一开始推个分层图最短路...然后发现并不是求最短路(躺
这题题目大意我没看错应该是这样的:
找一条1~n的路径,使路径上第k+1大的数尽可能的小
这个提法是不是有点眼熟...
假设有这样一个问题:
找一条1~n的路径,使路径上最大的数最小
“使最大的最小”,二分答案!
然后我就不会了
hzwer有一个很妙的思路orz...
大概是这个意思吧...
二分一下路径上最大的边权mx,然后对最短路变一下形
把>mx的边权当做1,<=mx的边权当做0,因为>mx的肯定要用一次减免不然就超出当前的答案了
二分答案不就是假设当前是最优的答案来确定更优的答案的区间在哪...
然后check()就是判断dis[n]<=k?0:1
1 #include<cstdio> 2 #include<cstring> 3 #define inf 0x7fffffff 4 struct poi{int to,nxt,V;}e[20005]; 5 int cnt,head[1005]; 6 inline void add(int u,int v,int V){ 7 e[++cnt]=(poi){v,head[u],V}; 8 head[u]=cnt; 9 } 10 int dis[1005],q[10005]; 11 bool vis[1005]; 12 int n,m,k,ans; 13 inline int max(int a,int b){return a>b?a:b;} 14 inline int min(int a,int b){return a<b?a:b;} 15 void spfa(int u,int mx) { 16 for(int i=1;i<=n;i++) dis[i]=inf; 17 dis[1]=0; q[0]=u; vis[u]=1; 18 int t=0,w=1; 19 while(t!=w) { 20 int now=q[t++]; 21 for(int i=head[now];i;i=e[i].nxt) { 22 int to=e[i].to; 23 if((dis[now]+((e[i].V>mx)?1:0))<dis[to]) { 24 dis[to]=dis[now]+((e[i].V>mx)?1:0); 25 if(!vis[to]) { 26 vis[to]=1; q[w++]=to; 27 } 28 } 29 } 30 vis[now]=0; 31 } 32 } 33 inline bool check(int mx) { 34 spfa(1,mx); 35 return dis[n]<=k; 36 } 37 int main() { 38 scanf("%d%d%d",&n,&m,&k); 39 int l=0,r=0; 40 for(int i=1;i<=m;i++) { 41 int u,v,V; 42 scanf("%d%d%d",&u,&v,&V); 43 if(u==v) continue; 44 add(u,v,V); add(v,u,V); 45 r=max(r,V); 46 } 47 ans=-1; 48 while(l<=r) { 49 int mid=(l+r) >> 1; 50 if(check(mid)){ans=mid;r=mid-1;} 51 else l=mid+1; 52 } 53 printf("%d ",ans); 54 }
以上是关于[Usaco2007 Jan]Telephone Lines架设电话线的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1614: [Usaco2007 Jan]Telephone Lines
BZOJ——1614: [Usaco2007 Jan]Telephone Lines架设电话线
[Usaco2007 Jan]Telephone Lines架设电话线
[Usaco2007 Jan]Telephone Lines架设电话线