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 }
时间: 2024-10-11 07:24:43

hdu1245+dij,堆优化的相关文章

dij+堆优化

写这个dij+堆优化的原因是有些地方卡SPFA,只能搞这个: 香甜的奶油: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<ctime> 7 #include<vector> 8 #include<algorithm> 9 #include&

迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少

首先来一段百度百科压压惊... 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 让我来翻译一下:Dijkstra可以求出一个点到一个图中其他所有节点的最短路径,故也称对于单源最短路径的一种解法 算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即

单源最短路径(dij+堆优化)

单源最短路径的模板题,感谢同学余能的帮助~ #include<bits/stdc++.h> #define inf 2147483647 using namespace std; bool book [200004]; int cnt=0; int head[200020]; int n,m,qq; struct Edge { int to,next,w; }e[2000005]; struct Dis { int to,w; }dis[20000]; struct cmp1 { bool o

【洛谷P1462】【二分+堆优化dij】

题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 每次经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的. 歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少. 题目分析 题目说了那么多,其实就是让求在角色不死亡的情况

Dij的堆优化

#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define M 100000 #define pa pair<int,int>//优先比较第一个元素 using namespace std; int d[M],n,m,cnt,head[M],next[M],u[M],dis[M],num,s,t; b

bzoj3040 最短路+配对堆优化

3040: 最短路(road) Time Limit: 60 Sec  Memory Limit: 200 MBSubmit: 1859  Solved: 564[Submit][Status][Discuss] Description N个点,M条边的有向图,求点1到点N的最短路(保证存在).1<=N<=1000000,1<=M<=10000000 Input 第一行两个整数N.M,表示点数和边数.第二行六个整数T.rxa.rxc.rya.ryc.rp. 前T条边采用如下方式生成

BZOJ 3040 最短路(road) 堆优化Dijkstra

题目大意:最短路. 思路:最短路. 贴一份比较高效的堆优化Dij模板吧. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define _MAX 1000010 #define MAX 10000010 using namespace std; #define min(a,b) ((a) < (b) ? a:b) long long

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

【Dijstra堆优化】HDU 3986 Harry Potter and the Final Battle

http://acm.hdu.edu.cn/showproblem.php?pid=3986 [题意] 给定一个有重边的无向图,T=20,n<=1000,m<=5000 删去一条边,使得1~n的最短路最长 求最短路最长是多少 [思路] 一定是删最短路上的边 可以先跑一个Dijkstra,求出最短路,然n后枚举删边 朴素的Dijkstra为n^2,枚举删边(n条)需要的总时间复杂度是n^3 堆优化Dijkstra(nlogn),总复杂度为n^2logn 有多重边,用邻接矩阵不方便,用邻接表方便,