• USACO 2008 January Silver Telephone Lines /// 二分最短路 邻接表dijkstra oj22924


    题目大意:

    一共有N (1 ≤ N ≤ 1,000)个电线杆,有P P (1 ≤ P ≤ 10,000)对电线杆是可以连接的,

    用几条线连接在一起的电线杆之间都可相互通信,现在想要使得电线杆1和电线杆N能相互通信,

    并且电线公司提出KK (0 ≤ K < N)条电线是可以免费使用的,

    当使用电线的数量超过K条,超出的电线要收费,

    收的总费用为去掉免费使用的K条电线之后最长的那条电线的长度。

    问最少费用是多少

    Input

    * Line 1: Three space-separated integers: NP, and K

    * Lines 2..P+1: Line i+1 contains the three space-separated integers: AiBi, 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

     
    /*
    这题二分猜测答案 用最短路dijkstra验证
    
    验证 猜测的mid是1~N的最短路中第k+1大的花费
    用dis[i]记录1到i点时 花费>= mid 的顶点数
    
    //若1~N没有路 则dis[n]始终为初始值INF
    //则二分猜测的答案始终正确 最终二分会被推到最右的点
    即无路 输出-1
    
    //若1~N有路但小于k+1条 则dis[n]始终<k+1
    //则二分猜测的答案始终错误 最终二分会被推到最左的点
    即无花费 输出0
    
    */
    
    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    struct NODE
    { /// 要放在vector里 需要重载小于号 按 val即花费 升序排序
        int to,val; // 到to点 花费val
        bool operator<(const NODE& x) const
          { return val < x.val; }
    };
    vector <NODE> vec[1005];
    int n,p,k,vis[1005],dis[1005];
    bool dijk(int mid)
    {
        for(int i=1;i<=n;i++)
            vis[i]=0, dis[i]=INF;
    
        priority_queue <NODE> q; ///优先队列自动升序排序
        NODE e;  e.to=1,e.val=0;
        q.push(e);  dis[1]=0;
    
        while(!q.empty())
        {
            e=q.top(); q.pop();
            vis[e.to]=0;
            vector <NODE> ::iterator it;
                for(it=vec[e.to].begin();it!=vec[e.to].end();it++)
                {
                    NODE tmp=*it;
                    if(vis[tmp.to]) continue;
                    int nowv=dis[e.to]+ (tmp.val>=mid ? 1:0);
                    /// tmp.val>=mid的话 说明在这条路上 到顶点tmp.to的路大于猜测值
                    /// 则dis[该点]为dis[上一点]+1 否则+0 先用nowv记录
                    
                    /// 与答案mid相等的也记录下来 若mid为正确答案 则恰好为第k+1个
                    /// 可能有多个花费等于mid 所以判断dis[n]>=k+1 
    
                    if(dis[tmp.to]>nowv)
                    {/// 之前记录过的比nowv大 说明nowv所在的这条才是较短的路
                        dis[tmp.to]=nowv;
                        vis[tmp.to]=1;
                        q.push(tmp);
                    }
                }
        }
        //printf("%d
    ",dis[n]);
        return dis[n]>=k+1;
    }
    int main()
    {
        while(~scanf("%d%d%d",&n,&p,&k))
        {
            for(int i=1;i<=n;i++)
                vec[i].clear();
                
            NODE e;
            while(p--)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                e.to=b, e.val=c;
                vec[a].push_back(e);
                e.to=a, e.val=c;
                vec[b].push_back(e);/// 无向图邻接表
            }
            
            int le=0,rig=1000005,ans=-1;
            while(le<=rig)
            {// 二分答案 mid为猜测值 进入dijk()验证 mid是不是第k+1条路
                int mid=(le+rig)/2;
                if(spfa(mid)) le=mid+1, ans=mid; ///mid在k个之后(太小或恰好)
                else rig=mid-1; ///mid在k个之内(太大) 缩小范围继续验证
            }
            if(ans>1000000) ans=-1; /// 说明dis[n] 一直在k个之后
            if(rig<0) ans=0;        /// 说明dis[n] 一直在k个之内
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    在ASP.NET开始执行HTTP请求的处理程序之前
    要在一般处理程序中获取其他页面的session值
    asp.net中session的原理及应用
    INTRAWEB说明书
    ASP.NET万能JSON解析器
    使用 IntraWeb (30)
    IntraWeb例子练习
    【整理】Asp.net HttpWebRequest和HttpWebResponse发送和接受任何类型数据
    Delphi 接口机制真相
    http://www.doc88.com/p-203939126010.html
  • 原文地址:https://www.cnblogs.com/zquzjx/p/8792923.html
Copyright © 2020-2023  润新知