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\n",z.w,z.path);
104         else printf("can't be saved\n");
105     }
106     return 0;
107 }

 

posted @ 2016-04-11 23:06  2014551532  阅读(462)  评论(0编辑  收藏  举报