zoukankan      html  css  js  c++  java
  • 洛谷P1948 [USACO08JAN]Telephone Lines S(分层最短路)

    题目地址:https://www.luogu.com.cn/problem/P1948

    题目描述:

    多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人。该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线。其他的由于地震使得无法连接。

    第i对电线杆的两个端点分别是ai,bi,它们的距离为li(1<=li<=1000000)。数据中每对(ai,bi)只出现一次。编号为1的电话杆已经接入了全国的电话网络,整个市的电话线全都连到了编号N的电话线杆上。也就是说,笨笨的任务仅仅是找一条将1号和N号电线杆连起来的路径,其余的电话杆并不一定要连入电话网络。

    电信公司决定支援灾区免费为此市连接k对由笨笨指定的电话线杆,对于此外的那些电话线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话线杆)。如果需要连接的电话线杆不超过k对,那么支出为0.

    请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?

    输入

    输入文件的第一行包含三个数字n,p,k;

    第二行到第p+1行,每行分别都为三个整数ai,bi,li。

    输出

    一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.

    题解:这又是一道简单的分层图最短路问题。分层图最短路可以看成是一个dp。也就是将当前图看做是一层,一共有k层,对于遍历到的每个结点,需要遍历其所连的直接边,那么对于每条边有两种操作,一种是这条边免费,那么就会进入到更高一层的图中进行操作,另一种是不免费,那么继续在当前图中进行遍历。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define S struct node
    const int N=1005;
    const int M=1e4+10;
    struct node{
        int dis,now,j;
        node(int a,int b,int c){
            dis=a,now=b,j=c;
        }
        bool operator> (const S s1) const {
            return dis>s1.dis; 
        }
    };
    struct st{
        int from,to,next,dis;
    }edge[M*2];
    int head[N],cnt=0,n,p,k,dis[N][N];
    void addedge(int u,int v,int w){
        cnt++;
        edge[cnt].from=u;
        edge[cnt].to=v;
        edge[cnt].dis=w;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void spfa(int s){
        memset(dis,0x3f,sizeof(dis));
        priority_queue<S,vector<S>,greater<S> >q;
        q.push(node(0,s,0));
        dis[0][s]=0;
        while(!q.empty()){
            S pa=q.top();q.pop();
            for(int i=head[pa.now];i;i=edge[i].next){
                if(dis[pa.j+1][edge[i].to]>dis[pa.j][pa.now]&&pa.j<k){
                    dis[pa.j+1][edge[i].to]=dis[pa.j][pa.now];
                    q.push(node(dis[pa.j][edge[i].to],edge[i].to,pa.j+1));
                }
                if(dis[pa.j][edge[i].to]>max(dis[pa.j][pa.now],edge[i].dis)){
                    dis[pa.j][edge[i].to]=max(dis[pa.j][pa.now],edge[i].dis);
                    q.push(node(dis[pa.j][edge[i].to],edge[i].to,pa.j));
                }
            }
        }
    }
    int main(){
        cin>>n>>p>>k;
        for(int i=1,u,v,w;i<=p;i++){
            cin>>u>>v>>w;
            addedge(u,v,w);
            addedge(v,u,w);
        }
        spfa(1);
        int ans=0x3f3f3f3f;
        for(int i=0;i<=k;i++){
        //    cout<<dis[i][n]<<endl;
            ans=min(ans,dis[i][n]);
        }
        if(ans==0x3f3f3f3f) cout<<"-1";
        else cout<<ans<<endl;
        return 0;
    }

    写于 202/8/12 23:08


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    MySql常用函数积累
    常用的linux命令
    Java replace和replaceAll
    json常用操作
    import { Subject } from 'rxjs/Subject';
    applicationCache
    mongo
    Mongodb更新数组$sort操作符
    Mongodb更新数组$pull修饰符
    使用forever运行nodejs应用
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13493676.html
Copyright © 2011-2022 走看看