• hdu2962 二分 + spfa


    题意:
          给你一个无向图,每条路径上都有自己的长度和最大承受高度,给你起点终点还有车的最大承装高度,问你高度最大的前提下路径最短是多少,求高度和路径.


    思路:

         这种类型题目太多了,就是给你一些限制,然后让你在这个限制的前提下找到另一个最优,涉及到线性单调的一般都可以直接二分枚举a掉,这个也不例外,二分高度,重新建图,或者在跑最短路的时候限制,都可以,具体看代码就懂了..


    #include<stdio.h>
    #include<string.h>
    #include<queue>
    
    #define N_node 1000 + 100
    #define N_edge 1000000 + 500
    #define INF 1800000000
    
    using namespace std;
    
    typedef struct
    {
       int to ,cost ,next;
    }STAR;
    
    typedef struct
    {
       int a ,b ,c ,d;
    }EDGE;
    
    EDGE edge[N_edge];
    STAR E[N_edge];
    int list[N_node] ,tot;
    int s_x[N_node];
    
    void add(int a ,int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    void spfa(int s ,int n)
    {
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = INF; 
       int mark[N_node] = {0};
       s_x[s] = 0;
       mark[s] = 1;
       queue<int>q;
       q.push(s);
       while(!q.empty())
       {
          int xin ,tou;
          tou = q.front();
          q.pop();
          mark[tou] = 0;
          for(int k = list[tou] ;k ;k = E[k].next)
          {
             xin = E[k].to;
             if(s_x[xin] > s_x[tou] + E[k].cost)
             {
                s_x[xin] = s_x[tou] + E[k].cost;
                if(!mark[xin])
                {
                   mark[xin] = 1;
                   q.push(xin);
                }
             }
          }
       }
       return ;                                    
    }
    
    bool ok(int mid ,int s ,int t ,int n ,int m)
    {
       memset(list ,0 ,sizeof(list));
       tot = 1;
       for(int i = 1 ;i <= m ;i ++)
       if(edge[i].c == -1 || edge[i].c >= mid)
       {
          add(edge[i].a ,edge[i].b ,edge[i].d);
          add(edge[i].b ,edge[i].a ,edge[i].d);
       }
       spfa(s ,n);
       return s_x[t] != INF;
    }
                
    int main ()
    {
       int n ,m ,i ,j;
       int s ,t ,w ,cas = 1;
       while(~scanf("%d %d" ,&n ,&m) && n + m)
       {
          if(cas != 1) puts("");
          for(i = 1 ;i <= m ;i ++)
          scanf("%d %d %d %d" ,&edge[i].a ,&edge[i].b ,&edge[i].c ,&edge[i].d);
          scanf("%d %d %d" ,&s ,&t ,&w);
          int up ,low ,mid;
          low = 0,up = w;
          int answ = -1 ,ansl;
          while(low <= up)
          {
             mid = (low + up) >> 1;
             if(ok(mid ,s ,t ,n ,m))
             {
                low = mid + 1;
                answ = mid;
                ansl = s_x[t];
             }
             else
             up = mid - 1;
          }
          printf("Case %d:
    " ,cas ++);
          if(answ == -1)
          printf("cannot reach destination
    ");
          else
          {
             printf("maximum height = %d
    " ,answ);
             printf("length of shortest route = %d
    " ,ansl);
          }
       }
       return 0;
    }
                

  • 相关阅读:
    java连接各种数据库
    java遗传算法
    java中‘==’和’equal‘的区别
    java.net.BindException: Address already in use: JVM_Bind错误,端口设置问题
    Flink学习笔记6 Flink原理-Task(任务)、Operator Chain(算子链)和Slot(资源)
    Flink学习笔记5 Flink原理-资源
    Flink学习笔记4 Flink原理-基础架构
    Flink学习笔记2 CentOS7.5搭建Flink1.6.1分布式集群
    Flink学习笔记1 Flink入门简介
    Dubbo学习笔记12:使用Dubbo中需要注意的一些事情
  • 原文地址:https://www.cnblogs.com/csnd/p/12063190.html
Copyright © 2020-2023  润新知