- 注意:距离要用long long,否则部分用例通不过!!!因为连续的小路会出现很多平方!!!
代码如下
#include<iostream>
#include<vector>
#include<stdio.h>
using namespace std;
const int N = 1010;
const long long INF = 1e18;
int n,m;
struct node{
int vertex;
int type;
long long dis;
};
vector<node> v[N];
long long dis[N],trail[N]={0};
bool visit[N];
long long pf(long long n){
return n * n;
}
void dijkstra(int s){
dis[s] = 0;
for(int i = 1; i <= n; i++){
int index = -1;long long minn = INF;
for(int j = 1; j <= n; j++){
if(!visit[j]&&dis[j]<minn){
minn = dis[j];
index = j;
}
}
if(index == -1) break;
visit[index] = true;
for(int j = 0; j < v[index].size(); j++){
int vertex = v[index][j].vertex;
int type = v[index][j].type;
if(!visit[vertex]){
if(type == 1){
if(dis[index]-pf(trail[index])+pf(trail[index]+v[index][j].dis)<dis[vertex]){
dis[vertex] = dis[index]-pf(trail[index])+pf(trail[index]+v[index][j].dis);
trail[vertex] = trail[index]+v[index][j].dis;
}
}else{
if(dis[index]+v[index][j].dis < dis[vertex]){
dis[vertex] = dis[index]+v[index][j].dis;
trail[vertex] = 0;
}
}
}
}
}
}
int main()
{
int t,a,b;
long long c;
fill(dis, dis+N, INF);
fill(visit, visit+N, false);
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
scanf("%d%d%d%lld", &t, &a, &b, &c);
v[a].push_back({b,t,c});
v[b].push_back({a,t,c});
}
dijkstra(1);
printf("%d\n", dis[n]);
return 0;
}