takapt0226's diary

競技プログラミングのことを書きます

POJ 3662 Telephone Lines

解法

二分探索 + bfs
自分で支払う上限で二分探索する
判定方法は上限より大きい辺のコストを1、上限以下の辺のコストを0としたグラフ上でbfs
コストk以下で到達できればok

const int inf = ten(9);
int n, p, k;
vector<pint> e[1024];
bool bfs(int pay_upper)
{
    int cost[1024]; // num free uses
    fill(cost, cost + n, inf);
    deque<int> q;
    cost[0] = 0;
    q.push_back(0);
    while (!q.empty())
    {
	int v = q.front();
	q.pop_front();
	int c = cost[v];

	if (c > k)
	    return false;
	if (v == n - 1)
	    return true;

	for (int i = 0; i < e[v].size(); ++i)
	{
	    int l = e[v][i].first;
	    int to = e[v][i].second;

	    if (l <= pay_upper)
	    {
		if (c < cost[to])
		{
		    cost[to] = c;
		    q.push_front(to);
		}
	    }
	    else
	    {
		if (c + 1 < cost[to])
		{
		    cost[to] = c + 1;
		    q.push_back(to);
		}
	    }
	}
    }
    return false;
}
int main()
{
    scanf("%d%d%d", &n, &p, &k);
    vector<int> len;
    while (p--)
    {
	int u, v, l;
	scanf("%d%d%d", &u, &v, &l);
	--u, --v;
	e[u].pb(pint(l, v));
	e[v].pb(pint(l, u));
	len.pb(l);
    }
    len.pb(0);
    uniq(len);

    int low = -1, high = len.size();
    while (high - low > 1)
    {
	int mid = (low + high) / 2;
	if (bfs(len[mid]))
	    high = mid;
	else
	    low = mid;
    }
    int res = high == len.size() ? -1 : len[high];
    printf("%d\n", res);
}