忽略一个条件:可能具有连续的小路,跑一边裸的迪杰斯特拉算法,即可拿到80分
注意:边权可能会爆int,采用long long才可以
#include <iostream>
#include <cstring>
using namespace std;
const long long inf = 1e14;
long long edge[505][505]; //边的长度
bool vis[505]; //是否已经确定最短路径的长度
long long d[505]; //最短路径的长度
long long cur,a,b,c,n,m,flag,imin;
void init()
{
memset(edge,0,sizeof(edge));
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; ++i)
d[i] = inf;
vis[1] = cur = 1;
d[1] = 0;
for(int i=0; i<m; ++i) //处理各边长度
{
cin>>flag>>a>>b>>c;
if(flag == 1) c *= c;
if(edge[a][b]==0 || c < edge[a][b])
edge[a][b] = edge[b][a] = c;
}
}
int main()
{
cin>>n>>m;
init();
for(int i=1; i<=n-1; ++i) //要再次加入n-1个结点
{
for(int j=1; j<=n; ++j) //松弛当前结点的每一条出边
{
if(vis[j]==0 && edge[cur][j] && edge[cur][j] + d[cur] < d[j])
d[j] = edge[cur][j] + d[cur];
}
imin = inf;
for(int j=1; j<=n; ++j) //找到d值最小的结点
{
if(vis[j]==0 && imin > d[j])
{
imin = d[j];
cur = j;
}
}
vis[cur] = 1;
if(cur==n) break; //结点n的最短路径被找到,退出
}
cout<<d[n];
return 0;
}