RT,当不能重复经过点时,删除最短路上的每一条边,然后再分别跑最短路。
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
struct edge {
int nxt,to;
double val;
} e[40005];
int tot,head[205];
void add(int u,int v,double w) {
e[++tot].to=v;
e[tot].val=w;
e[tot].nxt=head[u];
head[u]=tot;
}
int n,m,s1,s2,x[205],y[205];
double ans=0x3f3f3f3f;
int f[205];
double d[205];
bool vis[205];
bool flag=false;
struct ed {
int u;
double w;
friend bool operator <(const ed a1,const ed b1) {
return a1.w>b1.w;
}
};
priority_queue<ed>q;
void dijkstra(int s) {
for(int i=1; i<=n; i++)d[i]=0x3f3f3f3f;
memset(vis,0,sizeof(vis));
d[s]=0;
q.push((ed) {
s,0
});
while(!q.empty()) {
int u=q.top().u;
q.pop();
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
double w=e[i].val;
if(u==s1&&v==s2)continue;
if(d[u]+w<d[v]) {
d[v]=d[u]+w;
if(flag==false)f[v]=u;
if(!vis[v]) {
vis[v]=true;
q.push((ed) {
v,d[v]
});
}
}
}
}
}
int dis(int x1,int y1,int x2,int y2) {
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int main() {
freopen("marsh.in","r",stdin);
freopen("marsh.out","w",stdout);
cin>>n>>m;
for(int i=1; i<=n; i++)cin>>x[i]>>y[i];
for(int i=1; i<=m; i++) {
int u,v;
cin>>u>>v;
if(u==v)continue;
add(u,v,sqrt(dis(x[u],y[u],x[v],y[v])));
add(v,u,sqrt(dis(x[u],y[u],x[v],y[v])));
}
dijkstra(1);
flag=true;
int t=n;
while(t!=1) {
s1=f[t],s2=t;
dijkstra(1);
ans=min(ans,d[n]);
t=f[t];
}
printf("%.2lf",ans);
return 0;
}