最短路的变形
在更新节点最短路的时候,记录上一个节点连续走过小道的长度,然后根据当前道路分类讨论即可。
#include<bits/stdc++.h>
#define ll long long
#define ios ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
using namespace std;
const int N=1e5+5;
int n,m,d[505],vis[505],last[505],INF=0x3f;
struct edge
{
ll to,w,f;
bool operator <(const edge &x)const
{
return w>x.w;
}
};
struct node
{
ll num,dist,pre;
bool operator <(const node &x)const
{
return dist>x.dist;
}
};
vector<edge>g[N];
void dij()
{
memset(d,INF,sizeof(d));
d[1]=0;
priority_queue<node>que;
que.push({1,0,0});
while(!que.empty())
{
node t=que.top();
que.pop();
if(vis[t.num]) continue;
vis[t.num]=1;
int n=t.num;
for(int i=0;i<g[n].size();i++)
{
edge e=g[n][i];
if(e.f==0)
{
if(e.w+d[n]<d[e.to])
{
d[e.to]=e.w+d[n];
last[e.to]=0;
que.push({e.to,d[e.to]});
}
}
else
{
ll sum=e.w*e.w+2*e.w*last[n];
if(sum+d[n]<d[e.to])
{
d[e.to]=sum+d[n];
last[e.to]=last[n]+e.w;
que.push({e.to,d[e.to]});
}
}
}
}
cout<<d[n]<<endl;
}
int main()
{
ios;
cin>>n>>m;
while(m--)
{
int t,a,b,c;
cin>>t>>a>>b>>c;
g[a].push_back({b,c,t});
g[b].push_back({a,c,t});
}
dij();
return 0;
}