zoukankan      html  css  js  c++  java
  • hdu4885 有 限制的最短路

    题意:
          给你起点终点,和一些加油站,和每次加油后的最大行驶距离,问你从起点到终点最少加油次数,要求两点之间必须走直线,见到加油站必须加油,也就是说如果想从a走到b,那么a,b连线上的加油站必须加油。

    思路:
          关键就是处理a,b,之间的点必须加油这个问题,我们可以排序,x小的或者x相等y小的在前面,然后枚举每条边,对于每个点为起点的边如果当前的斜率出现过,那么我们就可以不加这条边(或者是在费用上增加1后加上这条边),不加的原因是我们可以再后面加,比如a -> b ->c 我们可以 a ->b ,然后b->c,(也可以a->c 距离+1),标记每一个点为起点的斜率,斜率出现过就不加了,标记斜率可以用容器,总的建图时间复杂度是

    O(n*n*log(n)) log(n)是因为map操作需要一个log级的时间复杂度。


    斜率相同直接跳过

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    #include<math.h>
    #include<map>
    
    #define N_node 1000 + 100
    #define N_edge 1000000 + 1000
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef struct
    {
       int to ,next ,cost;
    }STAR;
    
    typedef struct
    {
       double x ,y;
       int id;
    }NODE;
    
    STAR E[N_edge];
    NODE node[N_node];
    int list[N_node] ,tot;
    int s_x[N_node];
    map<double ,int>hash;
    
    void add(int a ,int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    double dis(NODE a ,NODE b)
    {
       double x = (a.x - b.x) * (a.x - b.x);
       double y = (a.y - b.y) * (a.y - b.y);
       return sqrt(x + y);
    }
    
    bool camp(NODE a ,NODE b)
    {
       return a.x < b.x || a.x == b.x && a.y < b.y;
    }
    
    void spfa(int s ,int n)
    {
       int mark[N_node] = {0};
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = INF;
       queue<int>q;
       q.push(s);
       mark[s] = 1 ,s_x[s] = 0;
       while(!q.empty())
       {
          int xin ,tou;
          tou = q.front();
          q.pop();
          mark[tou] = 0;
          for(int k = list[tou] ;k ;k = E[k].next)
          {
             int 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);
                }
             }
          }
       }
    }
    
    int main ()
    {
       int n ,i ,j ,t;
       double L;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d %lf" ,&n ,&L);
          scanf("%lf %lf" ,&node[1].x ,&node[1].y);
          scanf("%lf %lf" ,&node[2].x ,&node[2].y);
          node[1].id = 1 ,node[2].id = 2;
          for(n += 2 ,i = 3 ;i <= n ;i ++)
          {
             scanf("%lf %lf" ,&node[i].x ,&node[i].y);
             node[i].id = i;
          }
          sort(node + 1 ,node + n + 1 ,camp);
          for(i = 1 ;i <= n ;i ++)
          {
             hash.clear();
             for(j = i + 1 ;j <= n ;j ++)
             if(dis(node[i] ,node[j]) <= L)
             {
                double xx = node[j].x - node[i].x;
                double yy = node[j].y - node[i].y;
                double v = xx == 0 ? -INF : yy / xx;
                if(hash[v]) continue;
                hash[v]  = 1;
                add(node[i].id ,node[j].id ,hash[v]);
                add(node[j].id ,node[i].id ,hash[v]);
             }
          }
          spfa(1 ,n); 
          int ans = s_x[2];
          ans == INF ? puts("impossible") : printf("%d
    " ,ans - 1);
       }
       return 0;
    }
    


    出现过的斜率那么就累加1的(跟上面的只有两行不同,其他的相同)

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    #include<math.h>
    #include<map>
    
    #define N_node 1000 + 100
    #define N_edge 1000000 + 1000
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef struct
    {
       int to ,next ,cost;
    }STAR;
    
    typedef struct
    {
       double x ,y;
       int id;
    }NODE;
    
    STAR E[N_edge];
    NODE node[N_node];
    int list[N_node] ,tot;
    int s_x[N_node];
    map<double ,int>hash;
    
    void add(int a ,int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    double dis(NODE a ,NODE b)
    {
       double x = (a.x - b.x) * (a.x - b.x);
       double y = (a.y - b.y) * (a.y - b.y);
       return sqrt(x + y);
    }
    
    bool camp(NODE a ,NODE b)
    {
       return a.x < b.x || a.x == b.x && a.y < b.y;
    }
    
    void spfa(int s ,int n)
    {
       int mark[N_node] = {0};
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = INF;
       queue<int>q;
       q.push(s);
       mark[s] = 1 ,s_x[s] = 0;
       while(!q.empty())
       {
          int xin ,tou;
          tou = q.front();
          q.pop();
          mark[tou] = 0;
          for(int k = list[tou] ;k ;k = E[k].next)
          {
             int 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);
                }
             }
          }
       }
    }
    
    int main ()
    {
       int n ,i ,j ,t;
       double L;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d %lf" ,&n ,&L);
          scanf("%lf %lf" ,&node[1].x ,&node[1].y);
          scanf("%lf %lf" ,&node[2].x ,&node[2].y);
          node[1].id = 1 ,node[2].id = 2;
          for(n += 2 ,i = 3 ;i <= n ;i ++)
          {
             scanf("%lf %lf" ,&node[i].x ,&node[i].y);
             node[i].id = i;
          }
          sort(node + 1 ,node + n + 1 ,camp);
          memset(list ,0 ,sizeof(list)) ,tot = 1;
          for(i = 1 ;i <= n ;i ++)
          {
             hash.clear();
             for(j = i + 1 ;j <= n ;j ++)
             if(dis(node[i] ,node[j]) <= L)
             {
                double xx = node[j].x - node[i].x;
                double yy = node[j].y - node[i].y;
                double v = (xx == 0 ? -INF : yy / xx);
                //if(hash[v]) continue;
                hash[v]  ++;
                add(node[i].id ,node[j].id ,hash[v]);
                add(node[j].id ,node[i].id ,hash[v]);
             }
          }
          spfa(1 ,n); 
          int ans = s_x[2];
          ans == INF ? puts("impossible") : printf("%d
    " ,ans - 1);
       }
       return 0;
    }
    

  • 相关阅读:
    数据库-第十章 数据库恢复技术-10.8 小结
    数据库-第十章 数据库恢复技术-10.7 数据库镜像
    数据库-第十章 数据库恢复技术-10.6 具有检查点的恢复技术
    SpringCloud系列之集成分布式事务Seata应用篇
    Redis数据迁移同步工具(redis-shake)
    SpringCloud系列之集成Dubbo应用篇
    SpringCloud系列之网关(Gateway)应用篇
    SpringCloud系列之服务注册发现(Eureka)应用篇
    SpringCloud系列之配置中心(Config)使用说明
    webService-axis开发jar包
  • 原文地址:https://www.cnblogs.com/csnd/p/12062914.html
Copyright © 2011-2022 走看看