【题目描述】:
平面上有n个点,每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。
【输入描述】:
输入文件共n+m+3行,其中:第一行为整数n。
第2行到第n+1行(共n行) ,每行两个整数x和y,描述了一个点的坐标。
第n+2行为一个整数m,表示图中连线的个数。
此后的m 行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点
【输出描述】:
输出文件仅一行,一个实数(保留5位小数),表示从s到t的最短路径长度。
【样例输入】:
5
0 0
2 0
2 2
0 2
3 1
5
1 2
1 3
1 4
2 5
3 5
1 5
【样例输出】:
3.41421
【时间限制、数据范围及描述】:
时间:1s 空间:128M
n<=100
本题可以用两点间距离公式dis=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))算出两点间边的路径长,然后再跑最短路即可
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<queue>
using namespace std;
const int M=1000005;
const int INF=1<<30;
int n,m,s,t;
int dist[M],Cost[M],Cnt;
struct Node{
int u,v,w,cost;
}Edge[M];
bool operator <(Node p,Node q){
return p.w<q.w;
}
void Push(int u,int v,int w){
Edge[++Cnt].Next=head[u];
Edge[Cnt].v=v;
Edge[Cnt].w=w;
head[u]=Cnt;
}
void dijkstra(){
priority_queue<Node> Q;
for(int i=1;i<=n;i++){
dist[i]=INF;
Cost[i]=INF;
}
dist[s]=0;
Cost[s]=0;
Q.push((Node){s,0,0});
while (!Q.empty()){
Node x=Q.top();
Q.pop();
for (int i=head[x.id];i;i=next[i])
if (x.d+adj[i]<dist[to[i]]||(x.d+adj[i]==dist[to[i]]&&Cost[to[i]]>x.v+val[i])){
dist[to[i]]=x.d+adj[i];
Cost[to[i]]=x.v+val[i];
Q.push((Node){to[i],dist[to[i]],Cost[to[i]]});
}
}
return;
}
int main(){
while (1){
n=get(),m=get();
if (n==0&&m==0) break;
memset(head,0,sizeof(head));
for (int i=1;i<=m;i++){
int u,v,w,p;
u=get(),v=get(),w=get(),p=get();
add(u,v,w,p);
add(v,u,w,p);
}
scanf("%d%d",&s,&t);
memset(dist,0,sizeof(dist));
memset(Cost,0,sizeof(Cost));
dijkstra();
printf("%d %d\n",dis[t],Cost[t]);
}
return 0;
}