zoukankan      html  css  js  c++  java
  • hdu1245 两个权值的最短路

    题意:
          求s到t的最短路,如果路径相同求那么要求另一个权值尽可能的小.
    思路:

          水题,就是spfa的比较那个地方多了一个可以更新的机会,当(s_x[xin] > s_x[tou] + E[k].cost || s_x[xin] == s_x[tou] + E[k].cost && s_t[xin] > s_t[tou] + 1) 时更新就行了..


    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<math.h>
    
    #define N_node 100 + 5
    #define N_edge 20000 + 500
    #define INF 1000000000
    
    using namespace std;
    
    typedef struct
    {
       int to ,next;
       double cost;
    }STAR;
    
    typedef struct
    {
       double x ,y;
    }NODE;
    
    STAR E[N_edge];
    NODE node[N_node];
    int list[N_node] ,tot;
    double s_x[N_node];
    int s_t[N_node];
    
    void add(int a ,int b ,double c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    double abss(double x)
    {
       return x > 0 ? x : -x;
    }
    double minn(double x ,double y)
    {
       return x < y ? x : y;
    }
    
    void SPFA(int s ,int n)
    {
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = INF ,s_t[i] = INF;
       int mark[N_node] = {0};
       mark[s] = 1;
       s_x[s] = s_t[s] = 0;
       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 || abss(s_x[xin] - s_x[tou] + E[k].cost) < 1e-6 && s_t[xin] > s_t[tou] + 1)
             {
                s_x[xin] = s_x[tou] + E[k].cost;
                s_t[xin] = s_t[tou] + 1;
                if(!mark[xin])
                {
                   mark[xin] = 1;
                   q.push(xin);
                }
             }
          }
       }
       return ;
    }
    
    int main ()
    {
       int n ,i ,j;
       double d;
       while(~scanf("%d %lf" ,&n ,&d))
       {
          for(i = 1 ;i <= n ;i ++)
          scanf("%lf %lf" ,&node[i].x ,&node[i].y);
          memset(list ,0 ,sizeof(list));
          tot = 1;
          for(i = 1 ;i <= n ;i ++)
          for(j = i + 1 ;j <= n ;j ++)
          {
             double dis = pow(node[i].x - node[j].x ,2.0) + pow(node[i].y - node[j].y,2.0);
             if(dis <= d * d) 
             {
                add(i ,j ,sqrt(dis));
                add(j ,i ,sqrt(dis));
             }
          }
          
          int s = 0 ,t = n + 1;
          for(i = 1 ;i <= n ;i ++)
          {
             double dis = pow(node[i].x,2.0) + pow(node[i].y ,2.0);
             if(pow(d + 7.5 ,2.0) >= dis)
             add(s ,i ,sqrt(dis) - 7.5);
             dis = minn(50 - abss(node[i].x) ,50 - abss(node[i].y));
             if(dis <= d) add(i ,t ,dis);
          }
          if(d >= 50 - 7.5)
          add(s ,t ,50 - 7.5);
          SPFA(s ,t);
          if(s_x[t] == INF)
          printf("can't be saved
    ");
          else
          printf("%.2lf %d
    " ,s_x[t] ,s_t[t]);
       }
       return 0;
    }
    


  • 相关阅读:
    AdminLTE模板
    日历插件
    Jquery 拖拽表格宽度
    Java桌面程序打包成exe可执行文件
    使用Access-Control-Allow-Origin解决跨域
    Ubuntu默认root密码
    Lua的require和module小结
    nginx 安装
    chkconfig命令
    [转]fedora启动telnet服务
  • 原文地址:https://www.cnblogs.com/csnd/p/12063147.html
Copyright © 2011-2022 走看看