试题编号: | 201712-4 |
试题名称: | 行车路线 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航。 输入格式 输入的第一行包含两个整数n, m,分别表示路口的数量和道路的数量。路口由1至n编号,小明需要开车从1号路口到n号路口。 输出格式 输出一个整数,表示最优路线下小明的疲劳度。 样例输入 6 7 样例输出 76 样例说明 从1走小道到2,再走小道到3,疲劳度为52=25;然后从3走大道经过4到达5,疲劳度为20+30=50;最后从5走小道到6,疲劳度为1。总共为76。 数据规模和约定 对于30%的评测用例,1 ≤ n ≤ 8,1 ≤ m ≤ 10; |
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3fffffff;
const int maxv=505;
typedef long long ll;
struct Node{
ll type,len,to;
};
vector<vector<Node>> adj(maxv);
ll d[maxv];
ll vis[maxv];
ll smallRoad[maxv];
ll n,m;
void Dijkstra(){
fill(d,d+maxv,INF);
fill(vis,vis+maxv,0);
fill(smallRoad,smallRoad+maxv,0);
d[1]=0;
for(ll i=0;i<n;++i){
ll u=-1,MIN=INF;
for(ll v=1;v<=n;v++){
if(vis[v]==0&&d[v]<MIN){
u=v;
MIN=d[v];
}
}
if(u==-1) break;
vis[u]=1;
for(ll j=0;j<adj[u].size();j++){
//ll v=adj[u][j].to;
if(adj[u][j].type==0){//大路
if(d[adj[u][j].to]>d[u]+adj[u][j].len){
d[adj[u][j].to]=d[u]+adj[u][j].len;
smallRoad[adj[u][j].to]=0;
}
}else{//小路
ll tmp;
//ll v=adj[u][j].to;
if(smallRoad[u]==0){
tmp=adj[u][j].len*adj[u][j].len;
if(d[adj[u][j].to]>d[u]+tmp){
d[adj[u][j].to]=d[u]+tmp;
smallRoad[adj[u][j].to]=adj[u][j].len;
}
}else{
tmp=(smallRoad[u]+adj[u][j].len)*(smallRoad[u]+adj[u][j].len);
tmp-=smallRoad[u]*smallRoad[u];//下方的d[u]需先减去
if(d[adj[u][j].to]>d[u]+tmp){
d[adj[u][j].to]=d[u]+tmp;
smallRoad[adj[u][j].to]=smallRoad[u]+adj[u][j].len;
}
}
}
}
}
}
int main(){
cin>>n>>m;
ll t,x,y,z;
Node tmp;
for(ll i=1;i<=m;++i){
cin>>t>>x>>y>>z;
tmp.type=t; tmp.to=y; tmp.len=z;
adj[x].push_back(tmp);
tmp.to=x;
adj[y].push_back(tmp);
}
Dijkstra();
cout<<d[n];
return 0;
}