热浪,一道中规中矩的最短路模版题,适合用来练手~
于是我分别用“邻接链表和SPFA”以及“邻接矩阵和dijstra”两种方法打了这道题,但实际方法还很多。
此外,我的代码写的有点个人化,不太适合看,希望有大牛能指点我一下代码方面的问题,感激不尽!
邻接链表和SPFA:
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
const int T=2500+5;
const int N=6200+5;
struct Edge{
int fm,to,val;
};
vector<Edge> v[N];
int t,c,ts,te;
int dis[T];
bool vis[T];
queue<int> q;
int main(){
scanf("%d %d %d %d",&t,&c,&ts,&te);
for(int i=1;i<=c;i++){
Edge edge;
scanf("%d %d %d",&edge.fm,&edge.to,&edge.val);
v[edge.fm].push_back(edge);
swap(edge.fm,edge.to);
v[edge.fm].push_back(edge);
}
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[ts]=0;
vis[ts]=true;
q.push(ts);
while( !q.empty()){
int point=q.front();
q.pop();
vis[point]=false;
for(int i=0;i<v[point].size();i++){
int npoint=v[point][i].to;
if ( v[point][i].val+dis[point]<dis[npoint] ){
dis[npoint]=v[point][i].val+dis[point];
if ( !vis[npoint] ) vis[npoint]=true,q.push(npoint);
}
}
}
printf("%d",dis[te]);
return 0;
}
邻接矩阵和dijstra:
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
const int T=2500+5;
const int N=6200+5;
int v[T][T];
int t,c,ts,te;
int dis[T];
bool vis[T];
vector<int> ex;
int main(){
scanf("%d %d %d %d",&t,&c,&ts,&te);
memset(v,INF,sizeof(v));
for(int i=1;i<=c;i++){
int fm,to,val;
scanf("%d %d %d",&fm,&to,&val);
v[fm][to]=v[to][fm]=val;
}
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[ts]=0;
ex.push_back(ts); // 将起点添加至可扩展点的集合之中
while( !ex.empty() ){ // 当前扩展点不为空
int minn=INF,npoint,pos;
for(int i=0;i<ex.size();i++)
if ( dis[ex[i]]<minn ) npoint=ex[i],minn=dis[ex[i]],pos=i; // 记录最短路径
vis[npoint]=true; // 加入访问过的集合
ex.erase(ex.begin()+pos); // 将其从可扩展点的集合除去
for(int i=1;i<=T;i++)
if ( dis[npoint]+v[npoint][i]<dis[i] ){
dis[i]=dis[npoint]+v[npoint][i]; // 更新路径
if ( !vis[i] ) ex.push_back(i); // 增加新的可扩展点
}
}
printf("%d",dis[te]);
return 0;
}
蒟蒻在成长~
2017.1.29