先从n号点开始跑dij,然后将从每一个点出发的边按到达的点到n号点的距离排序,然后dfs剪枝
跑得很快,每个点不到10ms,但是WA on #4
这是为什么?
#include<bits/stdc++.h>
using namespace std;
const int N=210,M=10010;
int x[N],y[N];
int n,m;
vector<pair<int,int> >g[N];
double dis[N][N];
double dist[N];
bool st[N];
bool vis[M];
typedef pair<double,int>node;
void dij(){
priority_queue<node,vector<node>,greater<node> >q;
q.push({0,n});
memset(dist,0x7f,sizeof dist);
dist[n]=0;
while(q.size()){
int t=q.top().second;q.pop();
if(st[t]) continue;
st[t]=1;
for(int i=0;i<g[t].size();i++){
int j=g[t][i].first;
if(st[j]) continue;
if(dist[j]>dist[t]+dis[t][j]){
dist[j]=dist[t]+dis[t][j];
q.push({dist[j],j});
}
}
}
}
bool cmp(pair<int,int>a,pair<int,int>b){
return dist[a.first]<dist[b.first];
}
double small=1e100,small2=1e100;
void dfs(int u,double len){
if(len+dist[u]>=small2) return;
//printf("%d %lf %d\n",u,len,loop);
if(u==n){
if(len<small){
small2=small,small=len;
}
else{
if(len<small2){
small2=len;
}
}
}
for(auto v:g[u]){
if(vis[v.second]) continue;
vis[v.second]=1;
dfs(v.first,len+dis[v.first][u]);
vis[v.second]=0;
if(len>=small2) return;
}
}
int main(){
//freopen("b.in","r",stdin);
//freopen("b.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=m;i++){
int a,b;scanf("%d%d",&a,&b);
g[a].push_back({b,i});
g[b].push_back({a,i});
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
dij();
if(dist[1]==1e100){
puts("-1");
return 0;
}
for(int i=1;i<=n;i++) sort(g[i].begin(),g[i].end(),cmp);
dfs(1,0);
if(small2==1e100){
puts("-1");
}
else{
printf("%.2lf\n",small2);
}
return 0;
}