POJ 2502 Dijkstra OR spfa
思路:
建完了图就是模板水题了 …..
但是建图很坑。
首先要把出发点向地铁站&终点 连一条边
地铁站之间要连无向边
地铁站向终点连一条边
以上的边权要*0.006
两个地铁站之间要连无向边 边权*0.0015
//By SiriusRen
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 40500
int n,ex,ey,cnt=1,tot=0;
int xx,yy,lastx,lasty;
struct node{int now;double weight;}jy,top;
double w[N],dis[333];
int v[N],next[N],first[333],px[N],py[N];
bool vis[333];
void add(int x,int y,double ww){
w[tot]=ww;v[tot]=y;
next[tot]=first[x];first[x]=tot++;
}
priority_queue<node>pq;
bool operator <(node a,node b){
return a.weight>b.weight;
}
void Dijkstra(){
jy.now=jy.weight=0;
pq.push(jy);
while(!pq.empty()){
top=pq.top();pq.pop();
if(vis[top.now])continue;
vis[top.now]=1;
for(int i=first[top.now];~i;i=next[i])
if(!vis[v[i]]&&dis[v[i]]>dis[top.now]+w[i]){
dis[v[i]]=dis[top.now]+w[i];
jy.now=v[i];
jy.weight=top.weight+w[i];
pq.push(jy);
}
}
}
queue<int>q;
void spfa()
{
q.push(0);
while(!q.empty())
{
int t=q.front();q.pop();
vis[t]=0;
for(int i=first[t];~i;i=next[i])
{
if(dis[v[i]]>dis[t]+w[i])
{
dis[v[i]]=dis[t]+w[i];
if(!vis[v[i]])q.push(v[i]),vis[v[i]]=1;
}
}
}
}
int main()
{
for(int i=1;i<=222;i++)dis[i]=0x3fffff;
memset(first,-1,sizeof(first));
scanf("%d%d%d%d",&px[0],&py[0],&ex,&ey);
scanf("%d%d",&lastx,&lasty);
px[cnt]=lastx;py[cnt]=lasty;
while(scanf("%d%d",&xx,&yy)){
if(xx==-1&&yy==-1){
if(scanf("%d%d",&lastx,&lasty)==EOF)break;
cnt++;
px[cnt]=lastx;py[cnt]=lasty;
continue;
}
add(cnt,cnt+1,sqrt((lastx-xx)*(lastx-xx)+(lasty-yy)*(lasty-yy))*0.0015);
add(cnt+1,cnt,sqrt((lastx-xx)*(lastx-xx)+(lasty-yy)*(lasty-yy))*0.0015);
lastx=xx,lasty=yy;
cnt++;
px[cnt]=lastx;py[cnt]=lasty;
}
px[++cnt]=ex;py[cnt]=ey;
for(int i=0;i<=cnt;i++)
for(int j=i+1;j<=cnt;j++){
add(i,j,sqrt((px[i]-px[j])*((px[i]-px[j]))+(py[i]-py[j])*(py[i]-py[j]))*0.006);
add(j,i,sqrt((px[i]-px[j])*((px[i]-px[j]))+(py[i]-py[j])*(py[i]-py[j]))*0.006);
}
spfa();
printf("%d\n",(int)(dis[cnt]+0.5));
}