POJ 3662

    一道神奇的二分搜索結合最短路判可行性的題。
    這道題首先是二分枚舉答案,然後對答案進行驗證,所以用這種方法做題必須要有一種能夠滿足時間限制的可行性判斷方法。這裏同樣是二分枚舉答案,不過這道題要注意不要枚舉出不存在的長度,所以要在一個記錄了已有長度的有序數組上進行二分搜索。
    接下來就是本題的重點——可行性判斷。首先要對圖進行轉化,如果邊的長度大於枚舉的值,則賦值爲1,否則賦值爲0。然後在該圖上求起點1到終點N的最短路,如果距離小於等於K,則說明存在一條路徑,John 只需支付L,否則意味着枚舉的值不滿足題目要求。
    順便說一下,題目中“the length of”意思是“……的長度”,而“k lengths of”意思是“k段……”,千萬注意。


代碼(G++):

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>

#define MAXP 10003
#define MAXN 1003
#define INF 20000
using namespace std;

typedef pair<int, int> pii;

struct Edge{
    int v;
    int len;
    int w;
} edges[MAXP*2];

int n, p, k, c, head[MAXN], next[MAXP*2], length[MAXP];

void add_edge(int u, int v, int len)
{
    edges[c].v = v;
    edges[c].len = len;
    next[c] = head[u];
    head[u] = c;
    c++;
}

void dijkstra(int s, int dist[])
{
    priority_queue<pii, vector<pii>, greater<pii> > pq;
    pii nd;
    int u, v;

    fill(dist+1, dist+n+1, INF);
    dist[s] = 0;
    pq.push(make_pair(dist[s], s));

    while(!pq.empty())
    {
        nd = pq.top();
        pq.pop();
        u = nd.second;
        if(dist[u] < nd.first) continue;
        for(int k=head[u]; k!=-1; k=next[k])
        {
            v = edges[k].v;
            if(dist[v] > dist[u] + edges[k].w)
            {
                dist[v] = dist[u] + edges[k].w;
                pq.push(make_pair(dist[v], v));
            }
        }
    }//for(int i=1; i<=n; i++) cout<<dist[i]<<endl;
}

bool is_ok(int L)
{
    int dist[MAXN];

    for(int i=0; i<c; i++)
    {
        if(edges[i].len > L) edges[i].w = 1;
        else edges[i].w = 0;
    }
    dijkstra(1, dist);

    if(dist[n] <= k) return true;
    else return false;
}

int main()
{
    int lb, ub, mid, a, b, e;
    while(scanf("%d %d %d", &n, &p, &k) != EOF)
    {
        c = 0;
        memset(head, -1, sizeof(head));
        for(int i=0; i<p; i++)
        {
            scanf("%d %d %d", &a, &b, &length[i]);
            add_edge(a, b, length[i]);
            add_edge(b, a, length[i]);
        }
        if(n == 1)
        {
            printf("%d\n", 0);
            continue;
        }
        length[p] = 0;
        length[p+1] = -1;
        sort(length, length+p+2);
        e = unique(length, length+p+2) - length;//cout<<e<<endl;
        lb = 0;
        ub = e;
        while(ub - lb > 1)
        {
            mid = (lb+ub) / 2;
            if(is_ok(length[mid])) ub = mid;
            else lb = mid;
        }
        if(ub == e) printf("-1\n");
        else printf("%d\n", length[ub]);
    }
    return 0;
}

題目
Telephone Lines
Time Limit: 1000MS Memory Limit: 65536K

Description

Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of the cables required to connect his farm to the phone system.

There are N (1 ≤ N ≤ 1,000) forlorn telephone poles conveniently numbered 1..N that are scattered around Farmer John's property; no cables connect any them. A total of P (1 ≤ P ≤ 10,000) pairs of poles can be connected by a cable; the rest are too far apart.

The i-th cable can connect the two distinct poles Ai and Bi, with length Li (1 ≤ Li ≤ 1,000,000) units if used. The input data set never names any {Ai, Bi} pair more than once. Pole 1 is already connected to the phone system, and pole N is at the farm. Poles 1 and N need to be connected by a path of cables; the rest of the poles might be used or might not be used.

As it turns out, the phone company is willing to provide Farmer John with K (0 ≤ K < N) lengths of cable for free. Beyond that he will have to pay a price equal to the length of the longest remaining cable he requires (each pair of poles is connected with a separate cable), or 0 if he does not need any additional cables.

Determine the minimum amount that Farmer John must pay.

Input

* Line 1: Three space-separated integers: N, P, and K
* Lines 2..P+1: Line i+1 contains the three space-separated integers: Ai, Bi, and Li

Output

* Line 1: A single integer, the minimum amount Farmer John can pay. If it is impossible to connect the farm to the phone company, print -1.

Sample Input

5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
Sample Output

4
發佈了151 篇原創文章 · 獲贊 35 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章