题目链接:点击打开链接
题意:给你n个点,m条边。再给你这个图中的一条最短路的的长度,接下来一行是你最短路上的各点,保证第一个是1,最后一个是n。然后接下来的m行是m条边。求是否还有其他的最短路。
题解:只要求出最短路的条数,即可。然后判断最短路的条数是否唯一,若唯一则没有,输出no,若不唯一则输出yes
最短路的题,我们只需在迪杰斯特拉算法中加一个pathnum【i】记录到达i的最短路的条数即可,当可以松弛时,就更新它,当相等时就pathnum【i】++。
看代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e4+5;
const int maxm = 2e6+6;
const int INF = 0x3f3f3f3f;
int head[maxn];
int dis[maxn];
int pathnum[maxn];
int book[maxn];
struct Edge{
int from;
int to;
int w;
int next;
}edge[maxm];
int n,m,len,cnt;
void add(int u,int v,int w){
edge[cnt].from = u;
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void dij(int s,int e){
memset(pathnum,0,sizeof(pathnum));
for(int i = 1 ; i <= n ; i ++){
dis[i] = INF;
//pathnum[i] = 1;
}
dis[s] = 0;
pathnum[1] = 1;
//book[s] = 1;
for(int i = 1 ; i <= n ; i ++){
int pos = 0;
int Min = INF;
for(int j = 1 ; j <= n ; j ++){
if(book[j] == 0 && Min > dis[j]){
pos = j;
Min = dis[j];
}
}
book[pos] = 1;
for(int k = head[pos] ; k != -1 ; k = edge[k].next ){
int u = edge[k].from;
int v = edge[k].to;
int w = edge[k].w;
if(dis[u] + w < dis[v] ){
dis[v] = dis[u] + w;
pathnum[v] = pathnum[u];
}
else if(dis[u] + w == dis[v]){
pathnum[v] ++;
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&len);
memset(head,-1,sizeof(head));
for(int i = 0 ; i < len ; i ++){
int a;scanf("%d",&a);
}
for(int i = 0 ; i < m ; i ++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dij(1,n);
if(pathnum[n] >= 2)
cout << "yes"<< endl;
else cout << "no" << endl;
}