最短路径2+记录所有最短路径+求最短路径的条数+重边问题
最短路径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;
}
}
Either Excellent or Rusty