[蓝桥杯 2020 省 AB3] 限高杆
chenhaoyou · · 题解
大意
货车要从
分析
很明显这是一道最短路的题(如果最短路不知道的看这个,最短路,大佬写的特别好 orz),问题就在于拆杆,这里有一点 dp 的思想,我们把不拆杆,拆一个杆,和拆两个杆分为三个不同的状态,在
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,x,y,z,d[11111][3],w,w1;//后面一维表示拆掉几个杆
bool vis[111111][3],b;
struct f{
int i,s;
bool b;//i 是编号,s 是边权,b 是这条路上有没有杆子
};
vector<f> a[111111];
void dji()
{
memset(d,127,sizeof(d));
priority_queue<pair<int,pair<int,int> >,vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int> > > > q;//三个参数分别是,最短路长度,目前拆了几个杆,当前节点的编号
d[1][0]=0;
q.push({0,{0,1}});
while(q.size())//模板,只差了一维
{
w=q.top().second.second;
w1=q.top().second.first;
q.pop();
if(vis[w][w1]) continue;
vis[w][w1]=1;
for(int i=0;i<a[w].size();i++)
{
if(a[w][i].b+w1>2) continue;//如果拆了超过两根杆就直接跳过
if(d[a[w][i].i][a[w][i].b+w1]>d[w][w1]+a[w][i].s)
{
d[a[w][i].i][a[w][i].b+w1]=d[w][w1]+a[w][i].s;
q.push({ d[a[w][i].i][a[w][i].b+w1] , {a[w][i].b+w1 , a[w][i].i } });
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x>>y>>z>>b;
a[x].push_back((f){y,z,b});
a[y].push_back((f){x,z,b});//别忘了建双向图
}
dji();
cout<<d[n][0]-min(d[n][1],min(d[n][2],d[n][0]));//求不拆杆和拆杆时路程的最大差值
return 0;
}