3662 Telephone Lines

問題概要

N個のノードとM個の辺からなる無向グラフで、1番のノードからN番のノードまで行くパスを作りたい。
好きなK本の辺は無料にしてもらえて、残りの辺のうち最大の長さがパスのコストになる。


パスのコストの最小値を求めよ。

解法

問題文がk種類の長さの辺を無料にするように読める気が……


長さlまでの辺の重みを0、lより大きい辺の重みを1にしたグラフで1番のノードからN番のノードまで最短で行く問題はダイクストラ法により解ける。
k本の辺が無料になるので、この最短路がk以下であれば、元の問題はl以下のコストのパスが存在することがわかる。


したがってlを二分探索で動かせばよい。

ソースコード

ダイクストラの辺の重みが全て0,1なので線形時間で出来ることを利用してみた。
ついでに辺にvectorを使わずにやってみたんだけど、実行時間が他の人より遅い……何故……

int n,m,k;
int e[1000],ne;
int t[20001],c[20001],nx[20001];

bool ok(int lim)
{
	deque<pi> Q; bool v[1000]={0};
	Q.pb(mp(0,0));
	while(!Q.empty())
	{
		int cc=Q.front().first,cur=Q.front().second; Q.pop_front();
		if(v[cur])continue;
		v[cur]=1; if(cur==n-1)return cc<=k;
		for(int i=e[cur];i;i=nx[i])if(!v[t[i]])
		{
			if(c[i]<=lim)Q.push_front(mp(cc,t[i]));
			else Q.pb(mp(cc+1,t[i]));
		}
	}
	return 0;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	ne=1;
	rep(i,m)
	{
		int a,b,d;
		scanf("%d%d%d",&a,&b,&d); a--; b--;
		nx[ne]=e[a];
		e[a]=ne; t[ne]=b; c[ne++]=d;
		nx[ne]=e[b];
		e[b]=ne; t[ne]=a; c[ne++]=d;
	}
	int lo=-1,hi=1000001,mid;
	while(lo+1<hi)
	{
		mid=(lo+hi)/2;
		if(ok(mid))hi=mid;
		else lo=mid;
	}
	printf("%d\n",hi==1000001?-1:hi);
	return 0;
}