https://vijos.org/p/1155
恶心的题目。。用dijkstra求次短路只有70分,只有删边才能AC,这里给出70分代码给大家参考。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#define ms(i,j) memset(i, j, sizeof(i));
using namespace std;
struct node
{
int x;
int y;
double v;
node(int xi,int yi,double vi) : x(xi), y(yi), v(vi) {}
};
const int maxn = 200 + 5;
vector<node> a[maxn];
int n,m;
int x[maxn], y[maxn];
double dist(int i, int j)
{
return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
double dis[maxn][2];//0´æ×î¶Ì·£¬1´æ´Î¶Ì·
bool ex[maxn][2];
void Dijkstra()
{
ms(ex,0);
int flag = 0;
for (int i=1;i<=n;i++)
{
dis[i][0]=dis[i][1]=100000000;
}
dis[1][0] = 0;
for (int i=1;i<2*n;i++)
{
double mini = 100000000;
int k = 0;
for (int j=1;j<=n;j++)
{
if (!ex[j][0]&&mini>dis[j][0])
{
flag = 0;
mini = dis[j][0];
k = j;
} else
if (!ex[j][1]&&mini>dis[j][1])
{
flag = 1;
mini = dis[j][1];
k = j;
}
}
if (k==0) return ;
ex[k][flag]=true;
for (int j=0;j<a[k].size();j++)
{
node p = a[k][j];
if (dis[p.y][0]>mini+p.v)
{
dis[p.y][1] = dis[p.y][0];
dis[p.y][0] = mini+p.v;
} else
if (dis[p.y][1]>mini+p.v)
{
dis[p.y][1] = mini+p.v;
}
}
}
}
int main ()
{
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 xi,yi;
scanf("%d%d", &xi,&yi);
double di = dist(xi,yi);
a[xi].push_back(node(xi,yi,di));
a[yi].push_back(node(yi,xi,di));
}
Dijkstra();
if (dis[n][1]>99999990) printf("-1\n"); else printf("%.2f\n", dis[n][1]);
return 0;
}