dijstra算法
这道题很简单。
用最短路可以简单通过。
关于 SPFA,他死了。所以我们来用 Dijkstra 算法来解决这个问题。
我们可以简单的发现我们可以用拆限高杆后的最短距离减不拆限高杆的最短距离。
问题来了,我们怎么记录拆的限高杆呢?
其实,我们可以每拆一个限高杆后加
让人激动的代码来了:
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y;
bool operator<(node l)const{
return l.y<y;
}
};
priority_queue<node>qi;
vector<node>vi[300005];
int n,m,a,b,c,d,di[30005];
bool vis[30005];
void dij(){
memset(vis,false,sizeof(vis));
memset(di,127,sizeof(di));
di[1]=0;
qi.push(node{1,0});
while(!qi.empty()){
int x=qi.top().x;
qi.pop();
if(vis[x]){
continue;
}
for(int i=0;i<vi[x].size();i++){
int a=vi[x][i].x,b=vi[x][i].y;
if(di[a]>di[x]+b){
di[a]=di[x]+b;
qi.push(node{a,di[a]});
}
}
vis[x]=true;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(d==0){
vi[a].push_back(node{b,c});
vi[b].push_back(node{a,c});
vi[a+n].push_back(node{b+n,c});
vi[b+n].push_back(node{a+n,c});
vi[a+n+n].push_back(node{b+n+n,c});
vi[b+n+n].push_back(node{a+n+n,c});
}
else{
vi[a].push_back(node{b+n,c});
vi[b].push_back(node{a+n,c});
vi[a+n].push_back(node{b+n+n,c});
vi[b+n].push_back(node{a+n+n,c});
}
}
for(int i=1;i<=n;i++){
vi[a].push_back(node{a+n,0});
vi[a+n].push_back(node{a+n+n,0});
}
dij();
if(di[n]-min(di[n*2],di[n*3])<0){
cout<<0;
return 0;
}
cout<<di[n]-min(di[n*2],di[n*3]);
}
感谢 Franz_Liszt 提供的 hack 数据,已改正。