各种最短路模板

 原创 http://blog.csdn.net/shuangde800 , By   D_Double  (转载请标明)


原创大佬的代码格式不是我喜欢的风格...所以都被我稍作修改了下...


1.    Dijkstra  普通版

#include<stdio.h>
#include<string.h>
const int N=105, INF=9999999;
int d[N], w[N][N],vis[N],n,m;
void Dijkstra(int src)
{
	int i,j,u,tmp;
    for(i=1;i<=n;i++)
    d[i]=INF;
    d[src]=0; 
    memset(vis, 0, sizeof(vis));
    for(i=1;i<=n;i++)
	{
        u=-1;
        for(j=1;j<=n;j++)
        {
        	if(!vis[j])
			{
	            if(u==-1||d[j]<d[u]) 
				u=j;
        	}
        }			
        vis[u]=1;
        for(j=1;j<=n;j++)
        {
        	if(!vis[j])
			{
            	tmp=d[u]+w[u][j];
            	if(tmp<d[j]) 
				d[j] = tmp;
        	}
        }			
    }
}
int main()
{
    int a,b,c,i,j;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        for(i=1;i<=n;i++)
		{
            w[i][i]=INF;
            for(j=i+1;j<=n;j++)
            w[i][j]=w[j][i]=INF;
        }
        for(i=0;i<m;i++)
		{
            scanf("%d%d%d",&a,&b,&c);
            w[a][b]=w[b][a]=c;
        }
        Dijkstra(1);
        printf("%d\n",d[n]);
    }
    return 0;
}


2. Dijkstra+邻接表(用数组实现)+优先队列优化

#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
const int N=20005;
const int INF=9999999;
typedef pair<int,int>pii;
priority_queue<pii, vector<pii>, greater<pii> >q;
int d[N], first[N], u[N], v[N], w[N], next[N],n,m;
bool vis[N];
// 无向图的输入,注意每输入的一条边要看作是两条边
void read_graph()
{
    memset(first,-1,sizeof(first)); //初始化表头
    for(int e=1;e<=m;e++)
	{
        scanf("%d%d%d",&u[e],&v[e],&w[e]);
        u[e+m]=v[e];
		v[e+m]=u[e]; 
		w[e+m]=w[e];  // 增加一条它的反向边       
        next[e]=first[u[e]];  // 插入链表
        first[u[e]]=e;
        next[e+m]=first[u[e+m]]; // 反向边插入链表
        first[u[e+m]]=e+m;
    }
}
void Dijkstra(int src)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) 
	d[i]=INF;
    d[src]=0;
    q.push(make_pair(d[src],src));
    while(!q.empty())
	{
        pii u=q.top(); 
		q.pop();
        int x = u.second;
        if(vis[x]) continue;
        vis[x]=true;
        for(int e=first[x];e!=-1;e=next[e])
        {
        	if(d[v[e]]>d[x]+w[e])
			{
	            d[v[e]]=d[x]+w[e];
	            q.push(make_pair(d[v[e]],v[e]));
       	 	} 
        }			
    }
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        read_graph();
        Dijkstra(1);
        printf("%d\n",d[n]);
    }
    return 0;
}


3. Dijkstra+邻接表(用vecor实现)+优先队列优化

#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
#include<vector>
using namespace std;
const int N=105;
const int INF=9999999;
typedef pair<int,int>pii;
vector<pii>G[N];
priority_queue<pii, vector<pii>, greater<pii> >q;
int d[N], first[N], u[N], v[N], w[N], next[N],n,m;
bool vis[N];
// 无向图的输入,注意没输入的一条边要看作是两条边
void read_graph()
{
	int a,b,c,i;
    for(i=1; i<=n;i++)
    G[i].clear();   
    for(i=1; i<=m;i++)
	{
        scanf("%d%d%d",&a,&b,&c);
        G[a].push_back(make_pair(b,c));
        G[b].push_back(make_pair(a,c));
    }
}
void Dijkstra(int src)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) 
	d[i]=INF;
    d[src]=0;
    q.push(make_pair(d[src], src));
    while(!q.empty())
	{
        pii t=q.top(); 
		q.pop();
        int u=t.second;
        if(vis[u]) continue;
        vis[u]=true;
        for(int v=0;v<G[u].size();v++)
        {
       		if(d[G[u][v].first] > d[u]+G[u][v].second)
			{
	            d[G[u][v].first] = d[u]+G[u][v].second;
	            q.push(make_pair(d[G[u][v].first],G[u][v].first));
	        }
        }		
    }
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        read_graph();
        Dijkstra(1);
        printf("%d\n", d[n]);
    }
    return 0;
}


4.Bellman-Ford算法

#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
const int N=20005;
const int INF=9999999;
int n, m, u[N],v[N],w[N], d[N];
// 无向图的输入,注意每输入的一条边要看作是两条边
inline void read_graph()
{
    for(int e=1;e<=m;e++)
    scanf("%d%d%d",&u[e],&v[e],&w[e]);
}
inline void Bellman_Ford(int src)
{
    for(int i=1;i<=n;i++) 
	d[i]=INF;
    d[src]=0;
    for(int k=0;k<n-1;k++)
	{
        for(int i=1;i<=m;i++)
		{ 
            int x=u[i],y=v[i];
            if(d[x]<INF)
			{
                if(d[y]>d[x]+w[i])
                d[y]=d[x]+w[i];
            }
            if(d[y]<INF)
			{
                if(d[x]>d[y]+w[i])
                d[x]=d[y]+w[i];
            }
        }
    }
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        read_graph();
        Bellman_Ford(1);
        printf("%d\n", d[n]);
    }
    return 0;
}


5.SPFA

#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
const int N=20005;
const int INF=2147483646>>1;
int n, m, first[N],next[N],u[N],v[N],w[N], d[N];
bool vis[N];
queue<int>q;
inline void read_graph()
{
    memset(first, -1, sizeof(first));
    for(int e=1;e<=m;e++)
	{
        scanf("%d%d%d",&u[e],&v[e],&w[e]);
        u[e+m]=v[e],v[e+m]=u[e],w[e+m]=w[e];
        next[e]=first[u[e]];
        first[u[e]]=e;
        next[e+m]=first[u[e+m]];
        first[u[e+m]]=e+m;
    }
}
void SPFA(int src)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
	d[i]=INF;
    d[src]=0;
    vis[src]=true;
    q.push(src);
    while(!q.empty())
	{
        int x = q.front();  
		q.pop();
        vis[x] = false;
        for(int e=first[x]; e!=-1; e=next[e])
		{
            if(d[x]+w[e] < d[v[e]])
			{
                d[v[e]] = d[x]+w[e];
                if(!vis[v[e]])
				{
                    vis[v[e]] = true;
                    q.push(v[e]);
                }
            }
        }
    } 
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        read_graph();
        SPFA(1);
        printf("%d\n", d[n]);
    }
    return 0;
}

6.Floyd算法

#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
const int N=105;
const int INF=2147483646;
int n, m, d[N][N];
inline void read_graph()
{
    for(int i=1;i<=n;i++)
	{
        d[i][i]=INF;
        for(int j=i+1;j<=n;j++)
        d[i][j]=d[j][i]=INF;
    }
    int a,b,c;
    for(int e=1;e<=m;e++)
	{
        scanf("%d%d%d",&a,&b,&c);
        d[a][b]=d[b][a]=c;
    }
}
inline void Floyd(int src)
{
    for(int k=1;k<=n;k++)
	{
        for(int i=1;i<=n;i++)
		{
            for(int j=1;j<=n;j++)
            {
            	if(d[i][k]<INF&&d[k][j]<INF)
             	d[i][j]=min(d[i][j], d[i][k]+d[k][j]);
            }                
        }
    }
}
int main()
{
    int a,b,c;
    while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)break;
        read_graph();
        Floyd(1);
        printf("%d\n", d[1][n]);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值