→题目链接←
双键值最短路,SPFA
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#define ll long long
#define inf 0X3f3f3f3f3f3f3f3fll
using namespace std;
struct node{
int to,len1,len2;
};
int s,e,m,n=0;
vector<node>v[3030];
ll dis[3030],num[3030];
bool vis[3030];
queue<int>q;
void link(int x,int y,int z1,int z2){
node t;
t.to=y;
t.len1=z1;
t.len2=z2;
v[x].push_back(t);
}
int main(){
scanf("%d%d%d",&s,&e,&m);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
vector<int>a;
for(int i=0; i<y; i++){
int z;
scanf("%d",&z);
n=max(n,z);
for(int j=0; j<a.size(); j++){
link(a[j],z,x,a.size()-j);
}
a.push_back(z);
}
}
for(int i=1; i<=n; i++){
dis[i]=inf;
num[i]=inf;
}
q.push(s);
dis[s]=0;
num[s]=0;
vis[s]=true;
while(!q.empty()){
int t=q.front();
q.pop();
vis[t]=false;
if(t==e)continue;
for(int i=0; i<v[t].size(); i++){
int to=v[t][i].to;
int len1=v[t][i].len1;
int len2=v[t][i].len2;
if(dis[to]>dis[t]+len1){
dis[to]=dis[t]+len1;
num[to]=num[t]+len2;
if(!vis[to])q.push(to),vis[to]=true;
}
else if(dis[to]==dis[t]+len1 && num[to]>num[t]+len2){
num[to]=num[t]+len2;
if(!vis[to])q.push(to),vis[to]=true;
}
}
}
if(dis[e]>=inf)printf("-1 -1\n");
else printf("%lld %lld\n",dis[e],num[e]);
return 0;
}