**
最短路径练习模板
**
1.Floyd算法
#include<iostream>
#include<cstdio>
using namespace std;
const int INF=1e6;
const int NUM=105;
int arr[NUM][NUM];
int n,m;
//邻接矩阵
void floyd(void)
{
int s=1;
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
if(arr[i][k]!=INF)
for(int j=1; j<=n; j++)
{
if(arr[i][j]>arr[i][k]+arr[k][j])
arr[i][j]=arr[i][k]+arr[k][j];
}
cout<<arr[s][n]<<endl;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
return 0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
arr[i][j]=INF;
}
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
arr[a][b]=arr[b][a]=c;
}
floyd();
}
return 0;
}
2.bellman-ford算法
#include<bits/stdc++.h>
using namespace std;
const int INF=1e6;
const int NUM=105;
struct edge
{
int u,v,w;
}e[10005];
int n,m,cnt;
int pre[NUM];
//打印路径
void print_path(int s,int t)
{
if(s==t)
{
printf("%d ",s);
return ;
}
print_path(s,pre[t]);
printf("%d\n",t);
}
//数组存边
void bellman()
{
int s=1;
int d[NUM];
for(int i=1;i<=n;i++)
{
d[i]=INF;
}
d[s]=0;
for(int k=1;k<=n;k++)
{
for(int i=1;i<=cnt;i++)
{
int x=e[i].u,y=e[i].v;
if(d[x]>d[y]+e[i].w)
{
d[x]=d[y]+e[i].w;
pre[x]=y;
}
}
}
printf("%d\n",d[n]);
print_path(s,n);
}
//可以判断有无负圈
/*
void bellman()
{
int s=1;
int d[NUM];
for(int i=2;i<=n;i++)
{
d[i]=INF;
}
d[1]=0;
int k=0;
bool update=true;
while(update)
{
k++;
update=false;
if(k>n)
{
printf("有负圈\n");
return ;
}
for(int i=0;i<=cnt;i++)
{
int x=e[i].u,y=e[i].v;
if(d[x]>d[y]+e[i].w)
{
update=true;
d[x]=d[y]+e[i].w;
}
}
}
printf("%d\n",d[n]);
}
*/
//邻接矩阵
/*
void bellman()
{
int s=1;
for(int i=1;i<=n;i++)
{
d[i]=INF;
}
d[s]=0;
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(d[j]>d[i]+graph[i][j])
d[j]=d[i]+graph[i][j];
}
}
printf("%d\n",d[n]);
}
*/
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)return 0;
cnt=0;
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[cnt].u=a;
e[cnt].v=b;
e[cnt].w=c;
cnt++;
e[cnt].u=b;
e[cnt].v=a;
e[cnt].w=c;
cnt++;
}
bellman();
}
return 0;
}
3.SPFA
邻接表+队列
#include<bits/stdc++.h>
using namespace std;
const int INF=1e6;
const int NUM=105;
struct edge
{
int from,to,w;
edge(int a,int b,int c){
from=a;to=b;w=c;}
};
vector <edge>e[NUM];
int n,m;
int pre[NUM];
void print_path(int s,int t)
{
if(s==t)
{
printf("%d ",s);
return ;
}
print_path(s,pre[t]);
printf("%d\n",t);
}
int spfa(int s)
{
int dis[NUM];
bool ing[NUM];
int Neg[NUM];
memset(Neg,0,sizeof(Neg));
Neg[s]=1;
for(int i=1;i<n;i++)
{
dis[i]=INF;ing[i]=false;
}
dis[s]=0;
queue<int >Q;
Q.push(s);
ing[s]=true;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
ing[u]=false;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].to,w=e[u][i].w;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
pre[v]=u;
if(!ing[v])
{
ing[v]=true;
Q.push(v);
Neg[v]++;
if(Neg[v]>n)
return 1;
}
}
}
}
printf("%d\n",dis[n]);
//print_path(s,n);
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)return 0;
for(int i=1;i<=n;i++)
{
e[i].clear();
}
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
spfa(1);
}
return 0;
}
链式前向星
#include<bits/stdc++.h>
using namespace std;
const int INF=INT_MAX/10;
const int NUM=1000005;
struct Edge
{
int to,next,w;
}edge[NUM];
int n,m,cnt;
int pre[NUM];
int dis[NUM];
int head[NUM];
bool ing[NUM];
int Neg[NUM];
void print_path(int s,int t)
{
if(s==t)
{
printf("%d ",s);
return ;
}
print_path(s,pre[t]);
printf("%d\n",t);
}
void init()
{
for(int i=0;i<NUM;i++)
{
edge[i].next=-1;
head[i]=-1;
}
cnt=0;
}
void addedge(int u,int v,int w)
{
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int spfa(int s)
{
memset(Neg,0,sizeof(Neg));
Neg[s]=1;
for(int i=1;i<n;i++)
{
dis[i]=INF;ing[i]=false;
}
dis[s]=0;
queue<int >Q;
Q.push(s);
ing[s]=true;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
ing[u]=false;
for(int i=head[u];~1;i=edge[i].next)
{
int v=edge[i].to,w=edge[i].w;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
pre[v]=u;
if(!ing[v])
{
ing[v]=true;
Q.push(v);
Neg[v]++;
if(Neg[v]>n)
return 1;
}
}
}
}
printf("%d\n",dis[n]);
//print_path(s,n);
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
if(n==0&&m==0)return 0;
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
spfa(1);
}
return 0;
}
4.Dijkstra
#include<bits/stdc++.h>
using namespace std;
const int INF=1e6;
const int NUM=105;
struct edge
{
int from,to,w;
edge(int a,int b,int c)
{
from=a;
to=b;
w=c;
}
};
vector <edge>e[NUM];
struct s_node
{
int id,n_dis;
s_node(int b,int c)
{
id=b;
n_dis=c;
}
bool operator<(const s_node&a)const
{
return n_dis>a.n_dis;
}
};
int n,m;
int pre[NUM];
void print_path(int s,int t)
{
if(s==t)
{
printf("%d ",s);
return ;
}
print_path(s,pre[t]);
printf("%d\n",t);
}
void dijkstra()
{
int s=1;
int dis[NUM];
bool done[NUM];
for(int i=1; i<n; i++)
{
dis[i]=INF;
done[i]=false;
}
dis[s]=0;
priority_queue<s_node>Q;
Q.push(s_node(s,dis[s]));
while(!Q.empty())
{
s_node u=Q.top();
Q.pop();
if(done[u.id])
continue;
done[u.id]=true;
for(int i=0; i<e[u.id].size(); i++)
{
edge y=e[u.id][i];
if(done[y.to])
continue;
if(dis[y.to]>y.w+u.n_dis)
{
dis[y.to]=y.w+u.n_dis;
Q.push(s_node(y.to,dis[y.to]));
pre[y.to]=u.id;
}
}
}
printf("%d\n",dis[n]);
//print_path(s,n);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
return 0;
for(int i=1; i<=n; i++)
{
e[i].clear();
}
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
dijkstra();
}
return 0;
}