CCF CSP201714-4行车路线
思路:局部最优法,改写地杰斯特拉算法,把距离数组分成有无小路两部分
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 510,INF = 0x3fffffff;
struct Point{
int v,cost,road;
};
vector<Point>G[maxn];
int d[maxn][2];
bool flag[maxn];
int n;
void disj(int num){
fill(d[0],d[0]+maxn*2,INF);
memset(flag, false, sizeof(flag));
d[num][0] = d[num][1] = 0;
for(int i = 0; i < n; i++){
int u = -1;
long long mindis = INF;
for(int j = 1; j <= n; j++){
unsigned long long int dis = d[j][1] * d[j][1] + d[j][0];
//if(d[j][1] == INF && d[j][0] == INF) dis = INF;
if(flag[j] == false && mindis > dis){
mindis = dis;
u = j;
}
}
if(u == -1) return;
flag[u] = true;
for(int j = 0; j < G[u].size(); j++){
unsigned long long int dis1 = d[G[u][j].v][1] * d[G[u][j].v][1] + d[G[u][j].v][0];
// if(d[G[u][j].v][1] == INF && d[G[u][j].v][0] == INF) dis1 = INF;
unsigned long long int dis2;
if(flag[G[u][j].v] == false){
if(G[u][j].road == 1){
dis2 = (d[u][1]+G[u][j].cost)*(d[u][1]+G[u][j].cost)+d[u][0];
if(dis2 < dis1){
d[G[u][j].v][1] = d[u][1]+G[u][j].cost;d[G[u][j].v][0] = d[u][0];
}
}
else{
dis2 = d[u][1]*d[u][1]+d[u][0]+G[u][j].cost;
if(dis2 < dis1){
d[G[u][j].v][1] = 0;d[G[u][j].v][0] = dis2;
}
}
}
}
}
}
int main(){
int m;
cin>>n>>m;
for(int i = 0; i < m; i++){
int m1,m2;
Point point;
cin>>point.road>>m1>>m2>>point.cost;
point.v = m2;
G[m1].push_back(point);
point.v = m1;
G[m2].push_back(point);
}
disj(1);
cout<<(d[n][0]+d[n][1]*d[n][1]);
return 0;
}