最短路徑2+記錄所有最短路徑+求最短路徑的條數+重邊問題
阿新 • • 發佈:2020-10-07
最短路徑2
ECNU-1818
- 本題需要注意的一個問題就是重邊的問題,雖然這題的資料量很小,但是不能使用鄰接矩陣來儲存,也不能將重邊記為最小邊來計算。
- 這裡求最短路徑的條數有很多方法,我第一個想到的是使用dfs來遍歷,但是會超時。
- 有一個簡單的記錄最短路徑條數的方法是使用一個num陣列
/** * 這裡不能用鄰接矩陣的形式儲存整個圖,因為可能會出現重邊的問題。 * 如果是簡單的重邊,取最短邊即可,但是本題需要求出所有的最短路徑,所以更長的邊 * 對結果會有影響 */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<map> #include<vector> #include<unordered_map> #include<bitset> using namespace std; const int INF=0X3F3F3F3F; const int maxn=103; const int maxm=3003; int n,m; int d[maxn]; bool flag[maxn]; int weight[maxn][maxn]; vector<int>pre[maxn];//記錄所有的最短路徑 int ans; void dijkstra(int s){ for(int i=0;i<=n;i++){ d[i]=INF; } d[s]=0; for(int y=1;y<=n;y++){ int x=-1,mins=INF; for(int i=1;i<=n;i++){ if(!flag[i]&&d[i]<=mins){ mins=d[i]; x=i; } } if(x==-1){ continue; } flag[x]=true; for(int i=1;i<=n;i++){ if(i==x) continue; if(d[i]>d[x]+weight[x][i]){ d[i]=d[x]+weight[x][i]; pre[i].clear(); pre[i].push_back(x); }else if(d[i]==d[x]+weight[x][i]){ pre[i].push_back(x); } } } } void dfs(int cur){ if(cur==1){//遍歷到起點 ans++; return; } for(auto i:pre[cur]){ dfs(i); //往前遍歷 } } int main(){ cin>>n>>m; for(int i=0;i<=n;i++){ for(int j=0;j<=n;j++){ weight[i][j]=INF; } weight[i][i]=0; } for(int i=0;i<m;i++){ int u,v,w; cin>>u>>v>>w; weight[u][v]=min(weight[u][v],w); } dijkstra(1); ans=0; dfs(n); cout<<d[n]<<" "<<ans<<endl; return 0; }
/** * 這裡不能用鄰接矩陣的形式儲存整個圖,因為可能會出現重邊的問題。 * 如果是簡單的重邊,取最短邊即可,但是本題需要求出所有的最短路徑,所以更長的邊 * 對結果會有影響 */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<map> #include<vector> #include<queue> #include<unordered_map> #include<bitset> using namespace std; const int INF=0X3F3F3F3F; const int maxn=103; const int maxm=3003; int n,m; int top; int ans; int head[maxn]; int d[maxn]; int num[maxn]; vector<int>pre[maxn]; struct Node{ int to,dis; Node(){} Node(int a,int b):to(a),dis(b){} bool operator<(const Node& node)const{ return dis>node.dis; } }; struct Edge{ int to; int next; int cost; }; Edge edge[maxm]; void addEdge(int from,int to, int cost){ edge[top].to=to; edge[top].next=head[from]; edge[top].cost=cost; head[from]=top++; } void dijkstra(int s){ num[s]=1; // memset(d,INF,sizeof(d)); for(int i=0;i<=n;i++){ d[i]=INF; } d[s]=0; priority_queue<Node> que; que.push(Node(s,0)); while(!que.empty()){ Node now=que.top(); que.pop(); if(d[now.to]<now.dis) continue; for(int i=head[now.to];i!=-1;i=edge[i].next){ Edge e=edge[i]; if(d[e.to]>d[now.to]+e.cost){ d[e.to]=d[now.to]+e.cost; que.push(Node(e.to,d[e.to])); pre[e.to].clear(); pre[e.to].push_back(now.to); num[e.to]=num[now.to]; }else if(d[e.to]==d[now.to]+e.cost){ pre[e.to].push_back(now.to); num[e.to]+=num[now.to]; } } } } void dfs(int cur){ if(cur==1){//遍歷到起點 ans++; return; } for(auto i:pre[cur]){ dfs(i); //往前遍歷 } } int main(){ cin>>n>>m; top=0; memset(head,-1,sizeof(head)); for(int i=0;i<m;i++){ int u,v,w; cin>>u>>v>>w; addEdge(u,v,w); } dijkstra(1); ans=0; dfs(n); if(d[n]==INF){ cout<<"-1 0"<<endl; }else { cout<<d[n]<<" "<<num[n]<<endl; // cout<<d[n]<<" "<<ans<<endl; } }