用优先队列实现了dijkstra算法,写了两个函数说不定其他题也能用用,dijkstra(start,n)是找到从start到n的所有点的最短路径权值,dijkstra2(start,end,n)是在n个点中找到start到n的最短路径,输出都是最短路径以及最短路径数和一条最短路径
代码如下
#include<bits/stdc++.h>
#define maxn 110
#define inf 1e9
using namespace std;
struct node{
int sign;int weight;
};
class cmp{
public:
bool operator()(const node& x,const node& y){
return x.weight>y.weight;
}
};
priority_queue<node,vector<node>,cmp>q;
int a[maxn][maxn];
int weight[maxn];
bool sign[maxn];
int num[maxn];//count num
int num2[maxn][maxn];//store the same distance but different road form a to b
void init(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++)a[i][j]=inf;
}
}
node mp(int sign,int weight){
node x{sign,weight};
return x;
}
void dijkstra(int start,int n){
for(int i=1;i<=n;i++){
weight[i]=a[start][i];
}
vector<int>path[n+1];
memset(sign,false,sizeof(sign));
for(int i=0;i<n;i++){num[i+1]=1;weight[i+1]=inf;}
weight[start]=0;
q.push(mp(start,0));
while(!q.empty()){
node t=q.top();q.pop();
if(sign[t.sign])continue;
sign[t.sign]=true;
path[t.sign].push_back(t.sign);
for(int i=1;i<=n;i++){
if(!sign[i]&&weight[i]==t.weight+a[t.sign][i])num[i]+=num[t.sign]*num2[t.sign][i];
if(!sign[i]&&weight[i]>t.weight+a[t.sign][i]){
num[i]=num[t.sign]*num2[t.sign][i];
weight[i]=t.weight+a[t.sign][i];
path[i]=path[t.sign];
q.push(mp(i,weight[i]));
}
}
}//solve 1 to n all the shortest path
//output part
if(weight[n]==inf){
cout<<"-1"<<endl<<"0"<<endl<<"-1";}//can't find
else {
cout<<weight[n]<<endl<<num[n]<<endl;
for(int i=0;i<path[n].size();i++){
cout<<path[n][i]<<" ";//output one path
}
}
}
void dijkstra2(int start,int end,int n){
for(int i=1;i<=n;i++){
weight[i]=a[start][i];
}
vector<int>path[n+1];
memset(sign,false,sizeof(sign));
for(int i=0;i<n;i++){num[i+1]=1;weight[i+1]=inf;}
weight[start]=0;
q.push(mp(start,0));
while(!q.empty()){
node t=q.top();q.pop();
if(sign[t.sign])continue;
sign[t.sign]=true;
path[t.sign].push_back(t.sign);
for(int i=1;i<=n;i++){
if(!sign[i]&&weight[i]==t.weight+a[t.sign][i])num[i]+=num[t.sign]*num2[t.sign][i];
if(!sign[i]&&weight[i]>t.weight+a[t.sign][i]){
num[i]=num[t.sign]*num2[t.sign][i];
weight[i]=t.weight+a[t.sign][i];
path[i]=path[t.sign];
q.push(mp(i,weight[i]));
}
}
if(sign[end])break;//find the shortest path
}
//output part
if(weight[end]==inf){
cout<<"-1"<<endl<<"0"<<endl<<"-1";
}//unfind
else{
cout<<weight[end]<<endl<<num[end]<<endl;;
int sum=0;
for(int i=0;i<path[end].size();i++){
cout<<path[end][i]<<" ";//output one path
}
}
}//only find start to end's the shortest path
void solve(){
int n,m,l,r,k;cin>>n>>m;// n points and m paths
init();
for(int i=0;i<m;i++){
cin>>l>>r>>k;
if(a[l][r]>k){a[l][r]=k;num2[l][r]=1;a[r][l]=k;num2[r][l]=1;}
else if(a[l][r]==k){num2[r][l]++;num2[l][r]++;}
}//undirected graph
/*for(int i=0;i<m;i++){
cin>>l>>r>>k;
if(a[l][r]>k){a[l][r]=k;num2[l][r]=1;}
else if(a[l][r]==k){num2[l][r]++;}
}*/ //digraph
dijkstra(1,n);
//dijkstra2(1,n,n);
}
int main(){
solve();
}