• hdu1245+dij,堆优化


    有一片100*100的湖泊,中心坐标(0,0),即湖泊右上角的坐标是(50,50),湖泊中间有一片以(0,0)为圆心,15为直径的圆形陆地。现有一个人在陆地,湖泊中散布着一些点可以踩,这个人要利用这些点跳到岸上,求最短路径和最短路径下的最短步数。

    spfa莫名其妙的超时,dij+堆优化反而能过。。。可能spfa更适合有向图吧。

    使用vector<vector<node> > g这种双重结构时,最好先g.resize(N)设置一下容量,否则直接插入会出错。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<vector>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<queue>
      7 using namespace std;
      8 const double inf=1<<30;
      9 int n;
     10 double limit;
     11 struct node
     12 {
     13     double w;
     14     int v;
     15     int path;
     16     node(double ww,int vv,int ppath):w(ww),v(vv),path(ppath){}
     17     node(){}
     18     bool operator <(const node &dd) const
     19     {
     20         if(w!=dd.w)
     21         return w>dd.w;
     22         else
     23             return path>dd.path;
     24     }
     25 };
     26 vector<vector<node> > g;
     27 double dis(double x1,double y1,double x2,double y2)
     28 {
     29     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
     30 }
     31 double mmax(double aa,double bb)
     32 {
     33     if(aa>bb) return aa;
     34     else return bb;
     35 }
     36 int vis[110];
     37 
     38 int main()
     39 {
     40     double x[110],y[110];
     41     int i,j;
     42     while(scanf("%d%lf",&n,&limit)!=EOF)
     43     {
     44         priority_queue<node> q;
     45         g.clear();
     46         g.resize(n+10);
     47         for(i=1;i<=n;i++)
     48             scanf("%lf%lf",&x[i],&y[i]);
     49         for(i=1;i<=n;i++)
     50         {
     51             double dd=dis(x[i],y[i],0.0,0.0)-7.5;
     52             if(dd<=limit)
     53             {
     54                 g[0].push_back(node(dd,i,0));
     55                 g[i].push_back(node(dd,0,0));
     56             }
     57         }
     58         for(i=1;i<=n;i++)
     59         {
     60             for(j=i+1;j<=n;j++)
     61             {
     62                 double dd=dis(x[i],y[i],x[j],y[j]);
     63                 if(dd<=limit)
     64                 {
     65                     g[i].push_back(node(dd,j,0));
     66                     g[j].push_back(node(dd,i,0));
     67                 }
     68             }
     69         }
     70         double mm;
     71         for(i=1;i<=n;i++)
     72         {
     73             mm=mmax(fabs(x[i]),fabs(y[i]));
     74             if(50-mm<=limit)
     75             {
     76                 g[i].push_back(node(50-mm,n+1,0));
     77                 g[n+1].push_back(node(50-mm,i,0));
     78             }
     79         }
     80         //前面都是建图
     81         q.push(node(0,0,0));//放入起点
     82         memset(vis,0,sizeof(vis));//标记这个点的最短路是否已经求出
     83         node z;
     84         bool flag=false;//判断有无解
     85         while(!q.empty())
     86         {
     87             z=q.top();
     88             q.pop();
     89             if(vis[z.v]) continue;//这个点最短路已经求出,不需要继续求了
     90             vis[z.v]=1;//标记这个点的最短路已求出
     91             if(z.v==n+1) {flag=true;break;}//因为只需要求起点到n+1的最短路,所以可以结束了
     92             for(i=0;i<g[z.v].size();i++)
     93             {
     94                 node zz;
     95                 zz.v=g[z.v][i].v;
     96                 if(vis[zz.v]) continue;
     97                 zz.w=z.w+g[z.v][i].w;
     98                 zz.path=z.path+1;
     99                 q.push(zz);//反正是优先队列,不用管队列中是否已经存在zz,更新最短路的时候也不用管是否能使当前的最短路变得更短
    100             }
    101         }
    102         if(flag)
    103         printf("%.2f %d
    ",z.w,z.path);
    104         else printf("can't be saved
    ");
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    Redis学习(一)认识并安装redis
    并发编程(七)线程如何优雅地终止
    并发编程(六)Object类中线程相关的方法详解
    并发编程(五)线程同步
    并发编程(四)Thread类详解
    并发编程(三)线程池
    并发编程(二)Java中的多线程
    Python学习————作业
    Python学习————作业(面向对象)
    Python学习————面向对象和面向过程
  • 原文地址:https://www.cnblogs.com/mt522/p/5380658.html
Copyright © 2020-2023  润新知