zoukankan      html  css  js  c++  java
  • 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;
    }
                

  • 相关阅读:
    npmcnpmyarn yarn 关于源和代理的问题
    react : umi 引入 antd 踩坑
    Ant Design Pro 学习笔记:数据流向
    dva + umi 学习笔记
    简单分析 ztree 源码
    X-Tag实战:给博客加一个隐藏侧栏的功能
    javascript中var,let,const的区别
    linq 延迟执行带来的困扰
    如何实现能像windows 窗体一样改变大小的控件 Silverlight
    一个循环递归遍历问题
  • 原文地址:https://www.cnblogs.com/csnd/p/12063190.html
Copyright © 2011-2022 走看看