洛谷 P1744 【采购特价商品】题解
这道题要注意是双向边,不然四十分。。。还有就是要注意取绝对值,这样就可以通过勾股定理求出两点间的距离(不取貌似也可以,因为平方会将负数消掉)然后就可以直接spfa。这里我打了领接表,没看数据范围,所以内存开的有点大。下面是代码。这题目比较有良心,数据保证了两点能走到。还有就是要注意精度问题a,b数组必须开double,不然爆炸。(其他细节看代码)
#include<bits/stdc++.h> using namespace std; int la[500005],ne[500005],lnk[10005],q[500005*2],tot=0,n,m,s,t,x,y; int d[200000]; bool v[500005]; double co[500005],dis[10005],z,a[1005],b[1005]; long long sqr(long long x) { return x*x; } int add(int x,int y,double z) { tot++;ne[tot]=y;la[tot]=lnk[x];lnk[x]=tot;co[tot]=z; } void spfa(int s) { int head,tail,now; head=0;tail=1; for (int i=1;i<=10005;i++) dis[i]=2000000000.0; memset(v,sizeof(v),false); memset(d,sizeof(d),0); d[tail]=s;v[s]=true;dis[s]=0; while (head<tail) { head++; now=d[head]; for (int k=lnk[now];k;k=la[k]) if (dis[ne[k]]>dis[now]+co[k]) { dis[ne[k]]=dis[now]+co[k]; if (v[ne[k]]==false) { v[ne[k]]=true; tail++; d[tail]=ne[k]; } } v[now]=false; } return; } int read() { int x=0;char c;bool f; f=true; c=getchar(); if (c=='-') f=false; while (c<'0'||c>'9')c=getchar(); while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); if (f==false) x=x*-1; return x; } int main() { n=read(); for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i],&b[i]); m=read(); for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); z=sqrt(sqr(abs(a[x]-a[y]))+sqr(abs(b[x]-b[y]))); add(x,y,z); add(y,x,z); } s=read();t=read(); spfa(s); //if (dis[t]>2000000000) {printf("-1");return 0;} printf("%.2lf",dis[t]); return 0; }