• P1948 [USACO08JAN]电话线Telephone Lines


    P1948 [USACO08JAN]电话线Telephone Lines

    题目描述

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


    又从花那扒来的好题!

    可以发现, 最终花的钱越多, 可以走的范围就越大, 间接导致需要消去的道路条数越少: 最终花的钱与花费条数成反比

    所以我们二分答案, 搞一个扫描线, 对于每一条边进行扫描, 边权小于等于扫描线建边, 权值为 (0) , 大于则建边权值为 (1) ,这样跑出来的最短路即为满足此花费需要花费的最少消去路径

    所以我们根据消去路径与 (k) 比较, 缩小区间最后确定答案即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    typedef long long LL;
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 100019,INF = 1e9 + 19;
    int head[maxn],nume = 1;
    struct Node{
        int v,dis,nxt;
        }E[maxn << 3];
    void add(int u,int v,int dis){
        E[++nume].nxt = head[u];
        E[nume].v = v;
        E[nume].dis = dis;
        head[u] = nume;
        }
    int num, nr, k;
    struct Road{
    	int u, v, dis;
    	}I[maxn];
    int d[maxn];
    bool inq[maxn];
    void init(){
    	for(int i = 1;i <= num;i++)d[i] = INF;
    	memset(head, 0, sizeof(head));
    	nume = 1;
    	}
    void SPFA(int s){
    	queue<int>Q;
    	d[s] = 0;
    	Q.push(s);
    	inq[s] = 1;
    	while(!Q.empty()){
    		int u = Q.front();Q.pop();inq[u] = 0;
    		for(int i = head[u];i;i = E[i].nxt){
    			int v = E[i].v, dis = E[i].dis;
    			if(d[u] + dis < d[v]){
    				d[v] = d[u] + dis;
    				if(!inq[v])Q.push(v), inq[v] = 1;
    				}
    			}
    		}
    	}
    bool check(int x){
    	init();
    	for(int i = 1;i <= nr;i++){
    		int u = I[i].u, v = I[i].v, dis = I[i].dis;
    		if(dis <= x)add(u, v, 0), add(v, u, 0);
    		else add(u, v, 1), add(v, u, 1);
    		}
    	SPFA(1);
    	if(d[num] <= k)return 1;
    	return 0;
    	}
    int search(int l, int r){
    	int ans;
    	while(l <= r){
    		int mid = (l + r) >> 1;
    		if(check(mid))ans = mid, r = mid - 1;
    		else l = mid + 1;
    		}
    	return ans;
    	}
    int main(){
    	num = RD();nr = RD();k = RD();
    	for(int i = 1;i <= nr;i++)I[i].u = RD(), I[i].v = RD(), I[i].dis = RD();
    	if(!check(INF)){printf("-1
    ");return 0;}
    	printf("%d
    ", search(1, 1000019));
    	return 0;
    	}
    
  • 相关阅读:
    Django连接SQL Server,安装相关扩展包及相关配置
    安装pipenv
    报错及网络上的解决方案
    Nucleus-SE迁移:未实现的设施和兼容性
    RTOS诊断和错误检查
    Nucleus SE RTOS初始化和启动
    Nucleus 实时操作系统中断(下)
    Nucleus 实时操作系统中断(上)
    系统时间
    应用程序计时器
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9374947.html
Copyright © 2020-2023  润新知