标签:sizeof 不用 pop 多个 pre return 链接 tor als
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840
思路:最短路的变式题
dijk 中vis表示是否被当作过最小点,因为堆中已经有这个点了但是没有被当作最小点过,所有堆中可能存在多个同一个点但是距离不一样,所以要进行标记。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,s,d;
int a[(int)1e3];
int pv[(int)1e3];
priority_queue<pair<int,int>>q;
struct node{
int ne,v;
node(int _ne,int _v):ne(_ne),v(_v){}
};
vector<node> ve[(int)2e3+5];
int vis[(int)2e3];
int dis[(int)2e3];
int pre[(int)2e3];
int num[(int)2e3];
void dfs(int x){
if(x==s){
cout<<s;
return ;
}
dfs(pre[x]);
cout<<" "<<x;
}
void dij(){
memset(dis,0x3f3f3f3f,sizeof(dis));
q.push({0,s});
pv[s]=a[s];
dis[s]=0;
pre[s]=s;
num[s]=1;
while(q.size()){
int x=q.top().second;q.pop();//取完不用后尽快弹出
if(vis[x])continue;//已经被当作最小值点的直接忽略掉
vis[x]=1;
for(int i=0;i<ve[x].size();i++){
int y=ve[x][i].ne;
int len=ve[x][i].v;
if(dis[y]>dis[x]+len){
num[y]=num[x];
dis[y]=dis[x]+len;
pv[y]=pv[x]+a[y];
if(!vis[y])q.push({-dis[y],y});
pre[y]=x;
}
else if(dis[y]==dis[x]+len){
if(pv[y]<pv[x]+a[y]){
pv[y]=pv[x]+a[y];
pre[y]=x;
}
num[y]+=num[x];
}
}
}
cout<<num[d]<<" "<<pv[d]<<endl;
dfs(d);
}
int main (){
ios::sync_with_stdio(false);
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)cin>>a[i];
int l,r,v;
for(int i=1;i<=m;i++){
cin>>l>>r>>v;
ve[l].push_back(node(r,v));
ve[r].push_back(node(l,v));
}
dij();
return 0;
}
标签:sizeof 不用 pop 多个 pre return 链接 tor als
原文地址:https://www.cnblogs.com/abestxun/p/14692284.html