P1948 [USACO08JAN]电话线Telephone Lines spfa 二分答案

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1948 [USACO08JAN]电话线Telephone Lines spfa 二分答案相关的知识,希望对你有一定的参考价值。

  

多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人。该市周围分布着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.

 

输入输出样例

输入样例#1: 复制
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例#1: 复制
4

寻找 (路径1-n) 第k+1长的路并使之最小化
小于二分值的路 为0 大于则为1
技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 2147483647
#define N 500000+50
int dis[N],vis[N],head[N],n,m,s,pos,k,L,R,ans;
struct Edge

    int next,v,to;
edge[N];
void addedge(int a,int b,int c)

    edge[++pos]=Edgehead[a],c,b;
    head[a]=pos;

bool spfa(int x)

    queue<int>q;
    rep(i,1,n)
    dis[i]=inf,vis[i]=0;

    q.push(1);
    dis[1]=0;
    vis[1]=1;
    while(!q.empty())
    
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=edge[i].next)
        
            int v=edge[i].to;
            int w;
            if(edge[i].v<=x)w=0;
            else w=1;

            if(dis[v]>dis[u]+w)
            
                dis[v]=dis[u]+w;
                if(vis[v]==0)
                
                    vis[v]=1;
                    q.push(v);
                
            
        
    
    return dis[n]<=k;

int main()

    cin>>n>>m>>k;
    rep(i,1,m)
    
        int a,b,c;
        RIII(a,b,c);
        addedge(a,b,c);//有向边
        addedge(b,a,c);
        R=max(R,c);
    
    ans=-1;
    while(L<=R)
    
        int mid=(L+R)>>1;
        if(spfa(mid))R=mid-1,ans=mid;
        else L=mid+1;
    
    cout<<ans;
    return 0;
View Code

 





以上是关于P1948 [USACO08JAN]电话线Telephone Lines spfa 二分答案的主要内容,如果未能解决你的问题,请参考以下文章

P1948 [USACO08JAN]电话线Telephone Lines

洛谷P1948[USACO08JAN]电话线Telephone Lines

P1948 [USACO08JAN]电话线Telephone Lines

P1948 [USACO08JAN]电话线Telephone Lines spfa 二分答案

P1948 [USACO08JAN]Telephone Lines S(二分&01bfs)

P1948 [USACO08JAN]Telephone Lines S(二分&01bfs)