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

    2.电话网络(phone.cpp/in/out)

    [题目描述]

    由于地震使得连接汶川县城电话线全部损坏,假如你是负责将电话线接到震中汶川县城的负责人,汶川县

    城周围分布着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 #include <cstdio>
      2 #include <string>
      3 #include <cstring>
      4 #include <algorithm>
      5 using std::sort;
      6 long mid;   //二分中点值 
      7 bool used[1010];
      8 long map0[1010][1010];  //某点到某点的距离 
      9 long map[1010][1010];
     10 long dist[1010];
     11 long c[3010000];  //所有距离从小到大的排序 
     12 long que[2000010];
     13 long n, k;
     14 const long qmod = 2000000;
     15 long getint()    //这是个输入的分函数 
     16 {
     17     long rs=0;bool sgn=1;char tmp;
     18     do tmp = getchar();
     19     while (!isdigit(tmp)&&tmp-'-');
     20     if (tmp == '-'){tmp=getchar();sgn=0;}
     21     do rs=(rs<<3)+(rs<<1)+tmp-'0';
     22     while (isdigit(tmp=getchar()));
     23     return sgn?rs:-rs;    
     24 }
     25 void spfa()  //spfa求最短路径 
     26 {
     27     memset(dist,0x3f,sizeof dist); //初始化dis[]为无穷大 
     28     long l = 0;
     29     long r = 0;
     30     r ++;
     31     que[r] = 1;
     32     dist[1] = 0;
     33     while (l < r)
     34     {
     35         l ++;
     36         if (l == qmod)
     37             l = 0;
     38         long u = que[l];
     39         used[u] = false;
     40         for (long v=1;v<n+1;v++)
     41         {
     42             if (map0[u][v]<0x3f3f3f3f && dist[v]>dist[u]+map[u][v])
     43             {
     44                 dist[v] = dist[u] + map[u][v];
     45                 if (!used[v])
     46                 {
     47                     used[v] = true;
     48                     r ++;
     49                     if (r == qmod)
     50                         r = 0;
     51                     que[r] = v;
     52                 }
     53             }
     54         }
     55     }
     56 }
     57 bool can()
     58 {
     59     for (long i=1;i<n+1;i++)
     60     {
     61         for (long j=i;j<n+1;j++)
     62         {
     63             if (map0[i][j] == 0x3f3f3f3f)
     64                 map[i][j] = 0x3f3f3f3f;
     65             else if (map0[i][j] <= mid)
     66                 map[i][j] = map[j][i] = 0;
     67             else
     68                 map[i][j] = map[j][i] = 1;
     69         }
     70     }
     71     spfa();
     72     if (dist[n] > k)
     73         return false;
     74     else
     75         return true;
     76 }
     77 bool check()
     78 {
     79     for (long i=1;i<n+1;i++)
     80         for (long j=i;j<n+1;j++)
     81             map[i][j] = map[j][i] = 1; // 每条路都先赋值为 1 
     82     spfa();
     83     return dist[n] < 0x3f3f3f3f;
     84 }
     85 int main()
     86 {
     87 //    freopen("phone.in","r",stdin);
     88 //    freopen("phone.out","w",stdout);
     89     n = getint();
     90     long p = getint();
     91     k = getint();  //输入n,p,k; 
     92     memset(map0,0x3f,sizeof map0);  //初始化map[][] 全为0 ;
     93     for (long i=1;i<p+1;i++)
     94     {
     95         long a = getint();
     96         long b = getint();
     97         long cc = getint();     //输入起点和终点还有他们间距离 
     98         map0[a][b] = map0[b][a] = cc;
     99         c[++c[0]] = cc;   //将某两点之间的距离储存下来 
    100     }
    101     sort(c+1,c+1+c[0]);//进行排序(从小到大) 
    102     long tmp = 1;
    103     for (long i=2;i<c[0]+1;i++)
    104         if (c[i]!=c[tmp])
    105             c[++tmp] = c[i];  //把距离大小相等的合并起来 
    106     c[0] = 0;
    107     long l = 0;
    108     long r = tmp;
    109     long ans = 0x3f3f3f3f; //先把答案初始化为无穷大 
    110     if (!check())
    111     {
    112         printf("-1");
    113         return 0;
    114     }
    115     while (l <= r)
    116     {
    117         long mm = (l+r)>>1;
    118         mid = c[mm];
    119         if (can())
    120         {
    121             if (ans > mid)
    122                 ans = mid;
    123             r = mm-1;
    124         }
    125         else
    126         {
    127             l = mm+1;
    128         }
    129     }
    130     printf("%ld",ans);
    131     return 0;
    132 }

    ****把原图中距离大于x的电话线对应的边赋值为1,小于等于x的边赋值为0,变成一个01图,求最短路径,二分出答案

  • 相关阅读:
    java 中 堆、栈的区别(转)
    斐波那契数列(关于递归)
    .NetCore使用Hangfire
    大话西游系统文件分析
    VC游戏开发图片镂空
    华硕XTion Pro开发环境配置
    TweenMax 参数说明(中文翻译)
    程序员的追求
    最近得到的
    mvc的json
  • 原文地址:https://www.cnblogs.com/rax-/p/9057422.html
Copyright © 2011-2022 走看看