图论 最短路 difjstra 专题

本文详细介绍了Dijkstra算法的基本原理及其在不同场景中的应用案例,包括城市间最短路径计算、网络路由寻径等,并提供了多个编程实现示例。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <list>
#include <stack>
#include <queue>
using namespace std;
/*
	T3 hdu 2066
*/

int MAX=1111111111;
int mp[1002][1002];
int vis[1002];
int p[1002];
int main()
{
	int T,S,D;
	int a,b,time;
	int i,j;
	int maxn;
	while(cin>>T>>S>>D)
	{
		//初始化
		for(i=0;i<=1002;i++)
			for(j=0;j<=1002;j++)
				mp[i][j]=MAX;
		maxn=-1;//编号最大的城市
		for(i=1;i<=T;i++)
		{
			cin>>a>>b>>time;
			if(mp[a][b]>time)
				mp[a][b]=mp[b][a]=time;//两个方向
			if(maxn<a)
				maxn=a;
			if(maxn<b)
				maxn=b;
		}
		maxn++;
		//初始化起点
		for(i=1;i<=S;i++)
		{
			cin>>a;
			mp[0][a]=mp[a][0]=0;
		}
		//初始化终点
		for(i=1;i<=D;i++)
		{
			cin>>a;
			mp[a][maxn]=mp[maxn][a]=0;
		}

		//初始化vis 和p
		for(i=0;i<=maxn;i++)
		{
			vis[i]=0;
			p[i]=mp[0][i];
		}
		//difjstra
		vis[0]=1;
		p[0]=0;
		
		int min;
		int k;//标记
		for(i=0;i<=maxn;i++)
		{
			min=MAX;
			for(j=1;j<=maxn;j++)
			{
				if(vis[j]==0 &&min>p[j])
				{
					min=p[j];
					k=j;
				}
			}
			vis[k]=1;//最小的条路
			//选出来的最小的路,跟其他路径的比较
			for(j=1;j<=maxn;j++)
			{
				if(vis[j]==0 && p[j]>p[k]+mp[k][j])
					p[j]=p[k]+mp[k][j];
			}
		}
		cout<<p[maxn]<<endl;
	}
	return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <list>
#include <stack>
#include <queue>
using namespace std;

/*
	T2 hdu 3631
	*/
int MAX=100000000;
int mp[305][305];
int vis[305];


void flag(int x)
{
	for(int i=0;i<=304;i++)
	{
		if(mp[i][x] == MAX) continue;
		for(int j=0;j<=304;j++)
			if(mp[i][j]>mp[i][x]+mp[x][j] )
				mp[i][j]=mp[i][x]+mp[x][j];
	}
}
int main()
{
	int N,M,Q;
	int n,i,j;
	int x,y,c;
	n=1;
	while(cin>>N>>M>>Q ,N+M+Q)
	{
		if(n!=1) cout<<endl;
		for(i=0;i<=304;i++)
		{
			for(j=0;j<=304;j++)
				mp[i][j]= MAX;
			mp[i][i]=0;
		}
		while(M--)
		{
			cin>>x>>y>>c;
			if(mp[x][y] >c)
				mp[x][y]= c;
			if(x==y)
				mp[x][y] =0;
		}
		memset(vis,0,sizeof(vis));
		cout<<"Case "<<n<<":"<<endl;
		n++;
		while(Q--)
		{
			cin>>c;
			if(c==0)
			{
				cin>>x;
				if(vis[x] !=0)
					cout<<"ERROR! At point "<<x<<endl;
				else
				{
					vis[x]=1;
					flag(x);
					continue;
				}
			}
			if(c==1)
			{
				cin>>x>>y;
				if(vis[x] == 0 || vis[y]==0)
					cout<<"ERROR! At path "<<x<<" to "<<y<<endl;
				else if(mp[x][y] == MAX)
				{
					cout<<"No such path"<<endl;
				}
				else cout<<mp[x][y]<<endl;
			
			}
		}

	}

	return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <list>
#include <stack>
#include <queue>
using namespace std;


/*
	T1 hdu 2544
*/
int MAX=1111111111;
int mp[105][105];
int vis[105];
int p[105];
int main()
{
	int n,m;
	int i,j;
	while(cin>>n>>m && n!=0&& m!=0)
	{
		int a,b,c;
		//数组 初始化,
		memset(vis,0,sizeof(vis));
		memset(mp,-1,sizeof(mp));
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
				mp[i][j]=MAX;
			mp[i][i]=0;
		}
		while(m--)
		{
			cin>>a>>b>>c;
			mp[a][b]=mp[b][a] = c;
		}
		//difjstra
		vis[1]=1;
		int min,min_index,pos=1;
		//起始第一步
		for(i=2;i<=n;i++)
			p[i]=mp[1][i];
		for(j=1;j<=n-1;j++)
		{
			min=MAX;
			//找到
			for(i=1;i<=n;i++)
			{
				if(!vis[i] && mp[pos][i]!= -1 && min>p[i])
				{
					min=p[i];
					min_index=i;
				}
			}
			vis[min_index] =1;//这个点 已求
			pos=min_index;//记录这个点
			for(i=1;i<=n;i++)
			{
				if(!vis[i] && mp[pos][i] != -1 && p[i]>p[pos]+mp[pos][i])
					p[i] = p[pos] + mp[pos][i];
			}
		}
		cout<<p[n]<<endl;
	}
	return 0;
}
</pre><pre name="code" class="cpp">#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <list>
#include <stack>
#include <queue>
#define MAX 100000000
using namespace std;


/*
	T 2 poj 2387
*/
int mp[1005][1005];
int vis[1005];
int p[1005];
int main()
{
	int T,N;
	int i,j;
	int a,b,c;
	while(cin>>T>>N)
	{
		//数组初始化
		memset(vis,0,sizeof(vis));
		memset(mp,-1,sizeof(mp));
		for(i=1;i<=N;i++)
		{
			for(j=1;j<=N;j++)
				mp[i][j]=MAX;
			mp[i][i]=0;
		}
		for(i=0;i<T;i++)
		{
			cin>>a>>b>>c;
			if(mp[a][b]>c)
				mp[a][b]=mp[b][a]=c;
		}
		//difjstra
		vis[1]=1;
		int min,k,pos=1;
		//起始第一步
		for(i=1;i<=N;i++)
			p[i]=mp[1][i];

		for(j=1;j<=N;j++)
		{
			min=MAX;
			//找到
			for(i=1;i<=N;i++)
			{
				if(!vis[i] && min>p[i])
				{
					min=p[i];
					k=i;
				}
			}

			vis[k] =1;//这个点 已求
			pos=k;//记录这个点
			for(i=1;i<=N;i++)
			{
				if(!vis[i] && mp[pos][i] != MAX && p[i]>p[pos]+mp[pos][i])
					p[i] = p[pos] + mp[pos][i];
			}
		}
		cout<<p[N]<<endl;


	}

	return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <list>
#include <stack>
#include <queue>
#define MAX 100000000
using namespace std;


/*
	T1 hdu 2544
*/
int MAX=1111111111;
int mp[105][105];
int vis[105];
int p[105];
int main()
{
	int n,m;
	int i,j;
	while(cin>>n>>m && n!=0&& m!=0)
	{
		int a,b,c;
		//数组 初始化,
		memset(vis,0,sizeof(vis));
		memset(mp,-1,sizeof(mp));
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
				mp[i][j]=MAX;
			mp[i][i]=0;
		}
		while(m--)
		{
			cin>>a>>b>>c;
			mp[a][b]=mp[b][a] = c;
		}
		//difjstra
		vis[1]=1;
		int min,min_index,pos=1;
		//起始第一步
		for(i=2;i<=n;i++)
			p[i]=mp[1][i];
		for(j=1;j<=n-1;j++)
		{
			min=MAX;
			//找到
			for(i=1;i<=n;i++)
			{
				if(!vis[i] && mp[pos][i]!= -1 && min>p[i])
				{
					min=p[i];
					min_index=i;
				}
			}

			vis[min_index] =1;//这个点 已求
			pos=min_index;//记录这个点
			for(i=1;i<=n;i++)
			{
				if(!vis[i] && mp[pos][i] != -1 && p[i]>p[pos]+mp[pos][i])
					p[i] = p[pos] + mp[pos][i];
			}
		}
		cout<<p[n]<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值