卧薪尝胆,厚积薄发。
USACO2007JAN SILVER Telephone Lines
Date: Sat Nov 03 21:04:42 CST 2018 In Category: NoCategory

Description:

给出一个图,把 $1$ 和 $n$ 联通的代价为这条路径上边权的最大值,可以免费提供任意 $k$ 条道路,求最小代价。
$1\leqslant n\leqslant 10^3,1\leqslant m\leqslant 10^4$

Solution:

二分答案,把 $>mid$ 的边权设为 $1$ ,其他为零,求 $1$ 到 $n$ 最短路是否小于等于 $k$ 。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cctype>
#include<cstring>
using namespace std;
int n,m,k;
#define MAXN 1010
#define MAXM 10010
struct edge
{
int to,nxt,v,l;
}e[MAXM << 1];
int edgenum = 0;
int lin[MAXN] = {0};
void add(int a,int b,int c)
{
e[++edgenum] = (edge){b,lin[a],c,0};lin[a] = edgenum;
e[++edgenum] = (edge){a,lin[b],c,0};lin[b] = edgenum;
return;
}
int d[MAXN];
bool v[MAXN];
bool check(int l)
{
for(int i = 1;i <= edgenum;++i)
if(e[i].v > l)e[i].l = 1;
memset(d,0x3f,sizeof(d));d[1] = 0;
queue<int> q;q.push(1);
while(!q.empty())
{
int k = q.front();q.pop();
v[k] = false;
for(int i = lin[k];i != 0;i = e[i].nxt)
{
if(d[e[i].to] > d[k] + e[i].l)
{
d[e[i].to] = d[k] + e[i].l;
if(!v[e[i].to])
{
q.push(e[i].to);
v[e[i].to] = true;
}
}
}
}
for(int i = 1;i <= edgenum;++i)e[i].l = 0;
return (d[n] <= k);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int a,b,c;
for(int i = 1;i <= m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int l = 0,r = 1000001,mid;
while(l < r)
{
mid = ((l + r) >> 1);
if(check(mid))r = mid;
else l = mid + 1;
}
if(l != 1000001)cout << l << endl;
else puts("-1");
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡