HDU 1874 图论模板复习

裸的最短路问题,复习一下图论的模板

http://acm.hdu.edu.cn/showproblem.php?pid=1874


SPFA 数组版本

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#define INF 99999999
using namespace std;
const int maxn = 222;
int mapp[maxn][maxn],n,m;
int vis[maxn], dis[maxn];

int SPFA(int st,int end){
    for(int i=0;i<n;i++){ // 初始化
        dis[i] = INF; vis[i] = 0;//G[i].clear();
    }
    queue<int>Q;
    dis[st] = 0; 
    vis[st] = 1; //起始点距离为0, 标记上
    Q.push(st);
    while(!Q.empty()){
        int vex = Q.front(); Q.pop();
        vis[vex] = 0; //  
        for(int i=0;i<n;i++){
            if( dis[i] > mapp[vex][i] + dis[vex]){
                dis[i] = mapp[vex][i] + dis[vex];
                if(!vis[i]){
                    vis[i] = 1;
                    Q.push(i);
                }
            }
        }
    }
    return dis[end];
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                mapp[i][j] = INF;
        int a,b,c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            if(c < mapp[a][b])
                mapp[a][b] = mapp[b][a] = c;
        }
        int s,e; 
        scanf("%d%d",&s,&e);
        int ans = SPFA(s,e);
        if(ans < INF) printf("%d\n",ans);
        else
            printf("-1\n");
    }
}

SPFA vector版本(邻接链表)

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#define INF 0xfffffff
using namespace std;
struct node{
    int v,len;
    node(int v = 0,int len=0):v(v),len(len){}
};
const int maxn = 222;
vector<node>G[maxn];
int dis[maxn];
int vis[maxn];
int n,m;
void init(){
    for(int i=0;i<maxn;i++){
        dis[i] = INF; vis[i] = 0;G[i].clear();
    }
}
int SPFA(int st,int end){
    vis[st] = 1; queue<int>Q;
    dis[st] = 0;
    Q.push(st);
    while(!Q.empty()){
        int vex = Q.front(); Q.pop();
        vis[vex] = 0;
        for(int i=0;i<G[vex].size();i++){
            int v = G[vex][i].v;
            if( dis[v] > G[vex][i].len + dis[vex] ){
                dis[v] = G[vex][i].len + dis[vex];
                if(!vis[v]){
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
    return dis[end];
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        init(); //
        for(int i=0;i<m;i++){
            int a,b,c; scanf("%d%d%d",&a,&b,&c);
            G[a].push_back(node(b,c));
            G[b].push_back(node(a,c));
        }
        int s,e; scanf("%d%d",&s,&e);
        int ans = SPFA(s,e);
        if(ans == INF) printf("-1\n");
        else
            printf("%d\n",ans);
    }
}



Floyed

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#define INF 0xfffffff
using namespace std;
const int maxn = 222;
int n,m;
int map[maxn][maxn];
void floyed(){ //k ,i ,j
	for(int k=0;k<n;k++)
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				if(map[i][j] > map[i][k] + map[k][j])
					map[i][j] = map[i][k] + map[k][j];
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				if(i == j) map[i][j] = 0;
				else map[i][j] = INF;
		int a,b,c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
			if(c < map[a][b]) //重边
				map[a][b] = map[b][a] = c;
        }
		int s,e; scanf("%d%d",&s,&e);
		floyed();
		if(map[s][e] == INF)
			printf("-1\n");
        else
			printf("%d\n",map[s][e]);
    }
	return 0;
}

Dijkstra vector版本(邻接链表)

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#define INF 0xfffffff
using namespace std;
const int maxn = 222;
int n,m;
int map[maxn][maxn];
int dis[maxn];
bool vis[maxn];
struct node{
    int v,len;
    node(int v=0,int len=0):v(v),len(len){}
};
vector<node>G[maxn];
int dijkstra(int st,int end){
    vis[st] = 1;
    for(int i=0;i<G[st].size();i++){
        int vex = G[st][i].v;
        dis[vex] = min(dis[vex],G[st][i].len); // 消除重边
    }
    dis[st] = 0;
    for(int num = 1;num<n;num++){ //找到其余的n-1个点
        int tmp = INF, k;
        for(int i=0;i<n;i++){ //找到 距离最近的一个节点
            if(!vis[i] && tmp > dis[i] ){
                tmp = dis[i];
                k = i;
            }
        }
        vis[k] = true;
        if(tmp == INF) break; 
        for(int i=0;i<G[k].size();i++){
            int vex = G[k][i].v;
            if(!vis[vex] && dis[vex] > dis[k] + G[k][i].len  ){
                dis[vex] = dis[k] + G[k][i].len;
            }
        }
    }
    return dis[end];
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<n;i++){
            G[i].clear();
            vis[i] = 0; dis[i] = INF;
        }
        int a,b,c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            G[a].push_back(node(b,c));
            G[b].push_back(node(a,c));
        }
        int s,e; scanf("%d%d",&s,&e);
        int ans = dijkstra(s,e);
        if(ans == INF)
            printf("-1\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

Dijkstra 邻接矩阵

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#define INF 0xfffffff
using namespace std;
const int maxn = 222;
int n,m;
int map[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int dijkstra(int st,int end){
	memset(vis,0,sizeof(vis));
	vis[st] = 1;
	for(int i=0;i<n;i++){
		dis[i] = map[st][i];
	}
	dis[st] = 0;
	for(int num = 1;num<n;num++){ //找到其余的n-1个点
		int tmp = INF, k;
		for(int i=0;i<n;i++){
			if(!vis[i] && tmp > dis[i]){
				tmp = dis[i];
				k = i;
			}
		}
		vis[k] = true;
		if(tmp == INF) break; // 当前没有找到最短的节点
		for(int i=0;i<n;i++)
			if(!vis[i] && dis[i] > dis[k] + map[k][i] )
				dis[i] = dis[k] + map[k][i]; 
	}
	return dis[end];
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				map[i][j] = (i == j)? 0:INF; 
		int a,b,c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
			if(c< map[a][b])
				map[a][b] = map[b][a] = c;
        }
		int s,e; scanf("%d%d",&s,&e);
		int ans = dijkstra(s,e);
		if(ans == INF)
			printf("-1\n");
        else
			printf("%d\n",ans);
    }
	return 0;
}

Dijkstra 堆优化

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define MAXN 200 + 10
#define INF 0xffffff
using namespace std;
struct node{
    int v, len;
    bool operator < (const node & t) const{
        return len > t.len;
    }
    node(int v = 0, int len = 0):v(v), len(len){}
};
vector<node> G[MAXN];
bool vis[MAXN];
int dis[MAXN];
void Init(int n){
    for(int i = 0; i < n; i++){
        vis[i] = false;
        G[i].clear();
        dis[i] = INF;
    }
}
int dijstra_heap(int s,int t,int n){
    priority_queue<node>Q;
    dis[s] = 0;
    Q.push(node(s,0));
    while(!Q.empty()){
        node now = Q.top();
        Q.pop();
        int v = now.v;
        if(vis[v]) continue;
        vis[v] = true;
        for(int i=0;i<G[v].size();i++){
            int v2 = G[v][i].v; int len = G[v][i].len;
            if(!vis[v2] && dis[v] + len <dis[v2]){
                dis[v2] = dis[v] + len ;
                Q.push(node(v2,dis[v2])); //讲 dis[v2]放入堆中,利用logn的效率找到
                                            //距离最短的节点
            }
        }
    }
    return dis[t];
}
int main(){
    int n, m;
    int v1, v2, x, s, t;
    while(scanf("%d%d", &n, &m) != EOF){
        Init(n);
        for(int i = 0; i < m; i++){
            scanf("%d%d%d", &v1, &v2, &x);
            G[v1].push_back(node(v2, x));
            G[v2].push_back(node(v1, x));
        }
        scanf("%d%d", &s, &t);
        int ans = dijstra_heap(s, t, n);
        if(ans == INF)
            printf("-1\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(图论,最短路)