题意:
思路:
二分+Disjktra
二分一个值 如果某条边的边权比它小,则连上边权为0的边,否则连上边权为1的边
最后的d[n]就是最小要免费连接多少电话线。
//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 22222
int n,p,k,ans=-1,w[N],first[N],v[N],next[N],tot,d[N],vis[N];
void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
struct Node{int from,to,weight;}node[11111],jy;
bool operator<(Node a,Node b){return a.weight>b.weight;}
void Dijkstra(int x){
priority_queue<Node>pq;
memset(d,0x3f,sizeof(d));
memset(vis,0,sizeof(vis));
d[1]=0;jy.to=1,jy.weight=0;
pq.push(jy);
while(!pq.empty()){
Node t=pq.top();pq.pop();
if(!vis[t.to])vis[t.to]=1;
else continue;
for(int i=first[t.to];~i;i=next[i]){
if(!vis[v[i]]&&d[v[i]]>d[t.to]+w[i]){
d[v[i]]=d[t.to]+w[i];
jy.to=v[i],jy.weight=d[v[i]];
pq.push(jy);
}
}
}
}
bool check(int x){
memset(first,-1,sizeof(first)),tot=0;
for(int i=1;i<=p;i++)
{
if(node[i].weight<=x){
add(node[i].from,node[i].to,0);
add(node[i].to,node[i].from,0);
}
else
{
add(node[i].from,node[i].to,1);
add(node[i].to,node[i].from,1);
}
}
Dijkstra(x);
return d[n]<=k;
}
int main(){
scanf("%d%d%d",&n,&p,&k);
for(int i=1;i<=p;i++)
scanf("%d%d%d",&node[i].from,&node[i].to,&node[i].weight);
int l=0,r=0x3fffffff;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d
",ans);
}