POJ3662 Telephone Lines [二分 最短路]

来源:互联网 发布:阿里云 腾讯云哪个好 编辑:程序博客网 时间:2024/05/16 04:31

题意:

题目描述得挺隐晦。但是本质就一句话:求一条"最短路":第k+1大的边最小的"最短路"。

思路:

二分加最短路判定。

最答案进行二分。然后按照二分的值用0,1处理整个图:

将比二分值大的边都置为1,将比二分值小的边都置位0。然后进行找1到n的最短路,如果值小于K,则这个二分值满足题意。

再继续二分,直到找到最优解。


#include<iostream>#include<vector>#include<string>#include<queue>#include<algorithm>#define llong long long#define Min(a,b) (a<b?a:b)#define Max(a,b) (a>b?a:b)#define Abs(a) ((a)>0?(a):-(a))#define Mod(a,b) (((a)-1+(b))%(b)+1)using namespace std;const int N=1005;const int M=10005;const int inf=1e10;int n,m,K,k;int data[M][3];struct {int v,next,w;}edge[M<<1];int edgehead[N];bool vis[N];int d[N];void addedge(int u,int v,int w){edge[k].v=v;edge[k].w=w;edge[k].next=edgehead[u];edgehead[u]=k++;}bool OK(int value){queue<int> que;k=1;memset(edgehead,0,sizeof(edgehead));memset(edge,0,sizeof(edge));memset(vis,0,sizeof(vis));for(int i=1;i<=m;i++){if(data[i][2]<=value){addedge(data[i][0],data[i][1],0);addedge(data[i][1],data[i][0],0);}else{addedge(data[i][0],data[i][1],1);addedge(data[i][1],data[i][0],1);}}for(int i=1;i<=n;i++)d[i]=inf;que.push(1);vis[1]=true;d[1]=0;while(!que.empty()){int now=que.front();que.pop();vis[now]=false;for(int i=edgehead[now];i;i=edge[i].next){int v=edge[i].v;int w=edge[i].w;if(d[v]>d[now]+w){d[v]=d[now]+w;if(!vis[v]){que.push(v);}}}}if(d[n]<=K)return true;elsereturn false;}int main(){scanf("%d%d%d",&n,&m,&K);int l,r,rr=0,mid;for(int i=1;i<=m;i++){scanf("%d%d%d",data[i],data[i]+1,data[i]+2);rr=max(rr,data[i][2]);}l=0,r=rr+1;while(l<r){mid=(l+r)>>1;if(OK(mid)){r=mid;}else{l=mid+1;}}if(l<=rr)printf("%d\n",l);elseprintf("-1\n");return 0;}