替代加速,俄羅斯國產晶片 Troika 交通卡開始試用
阿新 • • 發佈:2022-04-13
1.Floyed(N3)
#include<iostream>
#include<cstring>
#define MAXN 1000
using namespace std;
int n,m,s,e,d;
bool vis[MAXN][MAXN];
int dis[MAXN][MAXN],w[MAXN][MAXN],pre[MAXN][MAXN];
inline void Floyed()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=k&&i!=j&&k!=j&&dis[i][k]+dis[k][j]<dis[i][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
pre[i][j]=pre[k][j];
}
}
void Print(int x)
{
if(pre[s][x]==0) return;
Print(pre[s][x]);
cout<<"—>"<<x;
}//輸出路徑需要pre陣列,儲存上一級位置
//弗洛伊德演算法,O(N*N*N),可處理負邊權,可以改動判斷連通圖
//vis[i][j]=vis[i][j]||(vis[i][k]&&dis[k][j])
int main()
{
memset(pre,0,sizeof(pre));
memset(dis,0x7f,sizeof(dis));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>s>>e>>d;
dis[s][e]=d;
dis[e][s]=d;
pre[s][e]=s;
pre[e][s]=e;
}
cin>>s>>e;//起始點和結束點
Floyed();
cout<<s;
Print(e);
cout<<endl<<dis[s][e];
return 0;
}
2.Dijkstra樸素演算法(N2)
#include<iostream>
#include<cstring>
#define MAXN 3000
#define INF 0xfffffff
using namespace std;
int n,m,s,e,d,k,minn,st,se;
bool vis[MAXN];
int dis[MAXN][MAXN],c[MAXN];
//待新增路徑輸出程式
int main()
{
memset(vis,0,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
cin>>n>>m>>s>>e;
for(int i=1;i<=m;i++)
{
cin>>st>>se>>d;
dis[st][se]=d;
dis[se][st]=d;
}
//初始化
for(int i=1;i<=n;i++) c[i]=dis[s][i];
vis[s]=true;
//Dijkstra
for(int i=1;i<=n-1;i++)
{
minn=INF;
k=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&c[j]<minn)
{
minn=c[j];
k=j;
}
if(k==0) break;
vis[k]=true;
for(int j=1;j<=n;j++)
if(c[k]+dis[k][j]<c[j])
c[j]=dis[k][j]+c[k];
}
cout<<c[e]<<endl;
return 0;
}
3.Dijkstra堆優化
#include<bits/stdc++.h>
#include<cstring>
#define MAXN 1003000
#define INF 0xfffffff
using namespace std;
int n,m,s,t,a,b,c,cnt=0;
struct egde
{
int to;
int dis;
int next;
}e[MAXN];
struct node
{
int dis;
int pos;
bool operator < (const node &x) const
{
return x.dis<dis;
}
};
int head[MAXN],dist[MAXN],vis[MAXN];
priority_queue<node> q;
void addedge(int u,int v,int w)
{
cnt++;
e[cnt].dis=w;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
};
void Dijkstra()
{
dist[1]=0;
q.push({0,1});
while(!q.empty())
{
node tmp=q.top();
q.pop();
int x=tmp.pos,d=tmp.dis;
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(dist[y]>dist[x]+e[i].dis)
{
dist[y]=dist[x]+e[i].dis;
q.push({dist[y],y});
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
addedge(a,b,c);
addedge(b,a,c);
}
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
Dijkstra();
cout<<dist[n];
return 0;
}
4.Bell-Ford演算法(N*M)
#include<iostream>
#include<cstring>
#define MAXN 1000
#define INF 0xfffffff
using namespace std;
int n,m,s,e,d;
struct line
{
int dist;
int start;
int end;
}w[MAXN];
bool vis[MAXN][MAXN];
int dis[MAXN];
int main()
{
memset(vis,0,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>s>>e>>d;
w[i].dist=d;
w[i].start=s;
w[i].end=e;
}
cin>>s>>e;
dis[s]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int u=w[j].start;
int v=w[j].end;
if(dis[u]+w[j].dist<dis[v])
dis[v]=dis[u]+w[j].dist;
/*v=w[j].start;
u=w[j].end;
if(dis[u]+w[j].dist<dis[v])
dis[v]=dis[u]+w[j].dist;*///反向計算雙向圖
}
cout<<dis[e];
return 0;
}
5.SPFA(K*M)//稠密圖會變慢,不太穩定,容易被卡,但很強大
#include<iostream>
#include<queue>
#include<cstring>
#define maxn 1005
#define maxm 2005
#define inf 0x3f3f3f
using namespace std;
queue<int> q;
int n,m,u,v,w,s,t,cnt=0;
int head[maxn],vis[maxn],dist[maxn];
struct node
{
int dis;
int next;
int to;
}e[maxm];
void addedge(int u,int v,int w)
{
cnt++;
e[cnt].to=v;
e[cnt].dis=w;
e[cnt].next=head[u];
head[u]=cnt;
}
void spfa(int s)
{
dist[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=false;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(dist[y]>(dist[x]+e[i].dis))
{
dist[y]=dist[x]+e[i].dis;
if(vis[y]==false)
{
q.push(y);
vis[y]=true;
}
}
}
}
}
int main()
{
cin>>n>>m>>s>>t;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
addedge(u,v,w);
}
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
spfa(s);
cout<<dist[t];
return 0;
}