图结构练习——最短路径
Problem Description
给定一个带权无向图,求节点1到节点n的最短路径。
Input
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。
Output
每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)
Sample Input
3 2
1 2 1
1 3 1
1 0
Sample Output
1
0
本题与图的最小生成树类似
代码如下(代码1为精简 代码2为详解)
1、
#include <iostream>
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
int x,y;
int flag[105];
int disv[105];
int n[105][105];
void zuiduan(int a)
{
int i,j,h,k;
for(i=1; i<=x; i++)
{
disv[i]=n[i][a];
}
disv[a]=0;
flag[a]=1;
for(i=1; i<x; i++)
{
int t=inf;
for(j=1; j<=x; j++)
{
if(flag[j]==0&&disv[j]<t)
{
t=disv[j];
h=j;
}
}
flag[h]=j;
for(k=1; k<=x; k++)
{
if(flag[k]==0&&disv[k]>disv[h]+n[h][k])
{
disv[k]=disv[h]+n[k][h];
}
}
}
}
int main()
{
int i,j,c,d,e,g;
while(cin >> x >> y)
{
g=y;
memset(flag,0,sizeof(flag));
for(i=1; i<=x; i++)
{
for(j=1; j<=x; j++)
{
if(i==j)
{
n[i][j]=0;
}
else
{
n[i][j]=inf;
}
}
}
while(y--)
{
cin >> c >> d >> e;
if(n[c][d]>e)
{
n[c][d]=n[d][c]=e;
}
}
if(g==0)
{
cout << 0 << endl;
}
else
{
zuiduan(1);
cout << disv[x] << endl;
}
}
return 0;
}
2、
#include <iostream>
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int mapp[105][105];
int flag[105];//是否访问过 相当于已经知道最短路的s集合
int dist[105];//储存起点到各个点的距离,dis[i]就是起点到i点的距离。
void Dijkstra(int v) //起始点 直接v = 1应该也可以
{
int i,j,k;
for(i=1; i<=n; i++) //dist数组的初始化
{
dist[i] = mapp[v][i];//1到各个点i的直接距离
flag[i] = 0;
}
dist[v] = 0;//自己到自己的距离为0
flag[v] = 1;
for(i=0; i<n-1; i++) //剩下的n-1个节点 依次遍历
{
int mi = inf;
int u;//中间节点
for(j=1; j<=n; j++) //寻找未标记节点的最小值 T集合的最小值
{
if(flag[j]==0&&dist[j]<mi)
{
mi = dist[j];
u = j;
}
}
flag[u] = 1;
for(k=1; k<=n; k++) //更新最短路
{
if(flag[k]==0 &&dist[k]>dist[u]+mapp[u][k])//T集合中 1直接到 k大于 1通过u到k的距离就更新
{
dist[k] = dist[u] + mapp[u][k];
}
}
}
}
int main()
{
int i,j,a,b,c;
while(cin >> n >> m)
{
memset(flag,0,sizeof(flag));
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(i==j)mapp[i][j]=0;
else mapp[i][j] = inf; //初始化地图数组
}
}
for(i=1; i<=m; i++)
{
cin >> a >> b >> c;
if(mapp[a][b]>c)
{
mapp[a][b] = mapp[b][a] = c;
}
}
if(m==0)cout << 0 <<endl;
else
{
Dijkstra(1);
cout << dist[n] <<endl;
}
}
return 0;
}