zoukankan      html  css  js  c++  java
  • 电话网络

    [题目描述]
    由于地震使得连接汶川县城电话线全部损坏,假如你是负责将电话线接到震中汶川县城的负责人,汶川县
    城周围分布着 N(1≤N≤1,000)根按 1..N 顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相
    连。一共 P(1≤P≤10,000)对电话线杆间可以拉电话线,其余的由于地震使得无法被连接。
    第 i 对电话线杆的两个端点分别为 Ai,Bi,它们间的距离为 Li(1≤Li≤1,000,000)。数据中保证每对
    (Ai,Bi)最多只出现 1 次。编号为 1 的电话线杆已经接人了全国的电话网络,整个县城的电话线全都连到了编
    号为 N 的电话线杆上。也就是说,你的任务仅仅是找一条将 1 号和 N 号电话线杆连起来的路径,其余的电话线
    杆并不一定要连人电话网络。
    电信公司决定支援灾区免费为汶川县城连结 K(0≤K<N)对由你指定的电话线杆。对于此外的那些电话线,需要
    为它们付费,总费用等于其中最长的电话线的长度(每根电话线仅连接一对电话线杆)。如果需要连接的电话线
    杆不超过 K 对,那么总支出为 0。
    请你计算一下,将电话线引到震中汶川县城最少需要在电话线上花多少钱?
    [输入格式]
    输入文件的第一行包含三个用空格隔开的整数:N,P 和 K。
    第二行到第 P+1 行:每行分别都为空格隔开的整数:Ai,Bi 和 Li。
    [输出格式]
    输出文件中仅包含一个整数,表示在这项工程上的最小支出。如果任务不可能完成,则输出-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
    [输出样例]
    4

    这个题怎么做?初看感觉好像没有任何思路。当时因为要求最小值,那么就想到了二分答案这样一种方法。但是当时没有想到的是如何二分,如果直接跑最短路显然不行,但是我们可以跑的是最短路上有多少条比当前二分的值边权大的边。直接对每一条边赋值即可,如果边权大于当前二分的值就赋为1否则为0,之后把这个当边权跑最短路即可。这样的话,我们就不停的二分答案就好了。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define inf 2147483647
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    int n,p,k,a,b,c,head[M],dis[M],cnt,r = M*10,l;
    bool vis[M],flag,pd[M];
    queue <int> q;
    struct node
    {
        int to,next,v,w;
    }e[M];
    inline int read()
    {
        int as = 0,fu = 1;
        char c = getchar();
        while(c < '0' || c > '9')
        {
            if(c == '-') fu = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
        {
            as = as * 10 + c - '0';
            c = getchar();
        }
        return as * fu;
    }
    
    void add(int x,int y,int z)
    {
        e[++cnt].to = y;
        e[cnt].v = z;
        e[cnt].next = head[x];
        head[x] = cnt;
    }
    
    void spfa(int s)
    {
        dis[s] = 0,vis[s] = 0;q.push(s);
        while(!q.empty())
        {
            int now = q.front();q.pop(),vis[now] = 0;
            for(int i = head[now];i;i = e[i].next)
            {
                if(dis[now] + e[i].w < dis[e[i].to])
                {
                    dis[e[i].to] = dis[now] + e[i].w;
                    if(!vis[e[i].to]) q.push(e[i].to),vis[e[i].to] = 1;
                }
            }
        }
    }
    int main()
    {
        freopen("phone.in","r",stdin);
        freopen("phone.out","w",stdout);
        n = read(),p = read(),k = read();
        rep(i,1,p) 
        {
            a = read(),b = read(),c = read();
            add(a,b,c);
            add(b,a,c);
        }
        while(l < r)
        {
            int mid = (l+r) >> 1;
            rep(i,1,cnt) 
            {
                if(e[i].v > mid) e[i].w = 1;
                else e[i].w = 0;    
            }
            rep(i,1,n) dis[i] = inf;
            spfa(1);
            if(dis[n] == inf) printf("-1
    "),exit(0);
    //        printf("%d %d
    ",mid,dis[n]);
            if(dis[n] > k) l = mid + 1;
            else r = mid;
        }
        printf("%d
    ",l);
        return 0;
    }
  • 相关阅读:
    了解node.js
    RC4 in TLS is Broken: Now What?
    LDAP 在ubuntu14.04下的安装配置install and configure
    Bucking the stigma (留学生请摘掉有色眼镜看社区大学)
    SSL Labs: Increased Penalty When TLS 1.2 Is Not Supported
    PostgresQL中的NUlls first/last功能
    网页小工具集合
    T-SQL在线格式化工具
    sudoers文件解析
    Java提高篇——JVM加载class文件的原理机制
  • 原文地址:https://www.cnblogs.com/captain1/p/9058565.html
Copyright © 2011-2022 走看看