窝这里Dijkstra是用的优先队列优化版的,适用于那些个卡时间卡空间的题目,用前向星存的图,老师上课讲的二维数组版的也没怎么听(QAQ)后面有空再补吧~
先贴代码:
Floyd (先来简单的)
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int t,n,m,dis[100][100];
string p[10][10];
string ch[]={"","A","B","C","D","E"};
void path(int x,int y,int z){
int sz=p[x][y].size();
string tp="";
for(int i=0;i<sz-1;i++)tp=tp+p[x][y][i];//拼接时去掉前部分最后一个字母避免重复
p[x][z]=tp+p[y][z];
}
int main(){
//ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j){
dis[i][j]=0;
p[i][j]="";
}
else{
dis[i][j]=inf;
p[i][j]=ch[i]+ch[j];
}
}
}
for(int i=0,u,v,w;i<m;i++){
cin>>u>>v>>w;
dis[u][v]=dis[v][u]=w;
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(k!=i&&k!=j&&i!=j)
if(dis[i][j]>dis[i][k]+dis[k][j]){
dis[i][j]=dis[i][k]+dis[k][j];
path(i,k,j);//记录路径
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%4d",dis[i][j]);
cout<<'\n';
}
cout<<'\n';
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
cout<<p[i][j]<<" ";
cout<<'\n';
}
return 0;
}
/*
5 7
1 2 10
2 3 50
1 4 30
1 5 100
3 5 10
3 4 20
4 5 60
*/
运行截图:
Dijkstra:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e4+5,M=2e5+5;
int ct,n,m,s,t,dis[N],head[N],vis[N];
int ans[N],las[N];//用于记录路径
struct edge{
int t,l,next;
}e[M];
struct ty{
int x,dis;
bool operator < (const ty & a)const{
return dis>a.dis;
}
};
priority_queue<ty> q;
void addedge(int u,int v,int w){//前向星存边
e[++ct].t=v;
e[ct].l=w;
e[ct].next=head[u];
head[u]=ct;
}
int Dij(int s,int t){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
ty tmp;
tmp.x=s, tmp.dis=0;
q.push(tmp);
while(!q.empty()){
tmp=q.top();
q.pop();
if(vis[tmp.x])continue;
vis[tmp.x]=1;
for(int i=head[tmp.x];~i;i=e[i].next){
int y=e[i].t;
if(dis[y]>dis[tmp.x]+e[i].l){
dis[y]=dis[tmp.x]+e[i].l;
ty tmp2;
tmp2.x=e[i].t, tmp2.dis=dis[y];
q.push(tmp2);
las[y]=tmp.x;//更新时记录上一个点
}
}
}
return dis[t];
}
int main(){
cin>>n>>m>>s>>t;//n:点个数,m:边数,s:起始点,t:终点
memset(head,-1,sizeof(head));
int x,y,z;
for(int i=0;i<m;i++){
cin>>x>>y>>z;
addedge(x,y,z);
addedge(y,x,z);
}
cout<<Dij(s,t)<<'\n';
ct=0;
int pos=t;
while(pos!=s){
ans[++ct]=pos,pos=las[pos];
}
cout<<s<<' ';
for(int i=ct;i>=1;i--)cout<<ans[i]<<' ';
return 0;
}
/*测试数据:
5 7 1 5
1 2 10
2 3 50
1 4 30
1 5 100
3 5 10
3 4 20
4 5 60
*/
运行截图:
太懒了
贴完跑路