POJ Telephone Lines 二分+dijkstra

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/happy_Du/article/details/74936640

题目链接: 点我
题目大意: 可以将T条边的权值改为0,然后选一条从起点到终点最大权值边最小的路。
题目分析: 二分最大权值x,然后dijkstra,遇到小于等于x的路长度为0,大于x的长度为1,总长度不能超过T即可。
PS :本来写的深搜结果超时了。。。


Problem: 3662       User: ChenyangDu
Memory: 516K        Time: 110MS
Language: C++       Result: Accepted

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

using namespace std;

const int maxn = 1000+5,INF = 10000000;
int n,m,K,d[maxn];

struct node{int v,d;};
node Node(int v,int d){
    node t;
    t.v = v;
    t.d = d;
    return t;
}
bool operator < (node a,node b){
    return a.d>b.d;
}

struct edge{int t,l;};
edge Edge(int t,int l){
    edge r;
    r.t = t;
    r.l = l;
    return r;
}
vector <edge> G[maxn];

bool bfs(int x){
    for(int i=2;i<=n;i++)d[i] = INF;
    d[1] = 0;
    priority_queue <node> que;
    que.push(Node(1,0));
    while(!que.empty()){
        node t = que.top();que.pop();
        if(t.v == n)return true;
        if(t.d > d[t.v])continue;
        for(int i=0;i<G[t.v].size();i++){
            edge e = G[t.v][i];
            int dd = e.l>x?1:0;
            if(d[e.t] > d[t.v] + dd){
                d[e.t] = d[t.v] + dd;
                if(d[e.t] <= K)que.push(Node(e.t,d[e.t]));
            }
        }
    }
    return false;
}

int main(){
    //freopen("in.txt","r",stdin);
    scanf("%d%d%d",&n,&m,&K);
    for(int a,b,l,i=0;i<m;i++){
        scanf("%d%d%d",&a,&b,&l);
        G[a].push_back(Edge(b,l));
        G[b].push_back(Edge(a,l));
    }
    int l = -1,r = INF;
    while(l<r-1){
        int mid = (r+l)>>1;
        if(bfs(mid))r = mid;
        else l = mid;
    }

    if(r == INF)cout<<"-1";
    else cout<<r;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/happy_Du/article/details/74936640