城市平乱—迪杰斯特拉算法



城市平乱

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市。

他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M。

现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都派遣了一个分队沿最近路去往暴乱城市平乱。

现在已知在任意两个城市之间的路行军所需的时间,你作为南将军麾下最厉害的程序员,请你编写一个程序来告诉南将军第一个分队到达叛乱城市所需的时间。

注意,两个城市之间可能不只一条路。

输入
第一行输入一个整数T,表示测试数据的组数。(T<20)
每组测试数据的第一行是四个整数N,M,P,Q(1<=N<=100,N<=M<=1000,M-1<=P<=100000)其中N表示部队数,M表示城市数,P表示城市之间的路的条数,Q表示发生暴乱的城市编号。
随后的一行是N个整数,表示部队所在城市的编号。
再之后的P行,每行有三个正整数,a,b,t(1<=a,b<=M,1<=t<=100),表示a,b之间的路如果行军需要用时为t

数据保证暴乱的城市是可达的。
输出
对于每组测试数据,输出第一支部队到达叛乱城市时的时间。每组输出占一行
样例输入
1
3 8 9 8
1 2 3
1 2 1
2 3 2
1 4 2
2 5 3
3 6 2
4 7 1
5 7 3
5 8 2
6 8 2 
样例输出
4
 
 
 
 
代码1:
 
 
用的大话数据结构上的迪杰斯特拉算法;邻接矩阵,时间长并且内存大;
 
 
 
 
 
#include<stdio.h>
#include<stdlib.h>
#define INT 65535

int N,M,P,Q, mini;
int G[1001][1001], team[1001],D[1001];

void shortestpath_dijstra()
{
	int v,w,min,k;
	int final[1001];
	for(v= 1; v <= M; v++)
	{
		final[v] = 0;
		D[v] = G[Q][v];
	}
	D[Q] = 0;
	final[Q] = 1;
	for(v = 1; v <= M; v++)
	{
		min = INT;
		for(w = 1; w <= M; w++)
		{
			if(!final[w] && D[w] < min)
			{
				k = w;
				min = D[w];
			}
		}
		final[k] = 1;
		for(w = 1; w <= M; w++)
		{
			if(!final[w] &&  G[k][w] != INT && (min + G[k][w] < D[w]))
			{
				D[w] = min + G[k][w];
			}
		}
	}
}

void create()
{
	int A, B, C,i;
	for(i =0; i < P; i++)
	{
		scanf("%d%d%d", &A, &B, &C);
		if(G[A][B] > C)
		{
			G[A][B] = C;
			G[B][A] = C;
		}
	}
}
void init()
{
	int i, j;
	for(i = 1; i <= M; i++)
	{
		for(j = 1; j <= M; j++)
		{
			if(i == j)
				G[i][j] = 0;
			G[i][j] = INT;
			
		}
	}
}

int main()

{
	int i,j, T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d%d", &N, &M, &P,&Q);
		init();
		for(i = 0; i < N; i++)
		{
			scanf("%d", &j);
			team[i] = j;
		}
		create();
		shortestpath_dijstra();
		mini = D[team[0]];
		for(i = 1; i < N; i++)
		{
			if(D[team[i]] < mini)
				mini = D[team[i]];
		}
		printf("%d\n", mini);
	}
	return 0;
}
        

        
代码2:
用的vector容器,算法也有不同,先从出发点更新好从出发点到可到达的点[i]的D[i];然后从所有的距离中选出最短的,并且该点不是已经求得最短的,从该点重复更新最短距离的操作;
 
D[v] 代表从战乱点到v点的当前最短距离;
 
 

#include<stdio.h>
#include<iostream>
using namespace std;
#include<vector>

typedef struct node
{
	int data;
	int weight;
}Node;
vector<Node> g[1001];
int N,M,P,Q, D[1001], team[101],mini;

void shortestpath_dijstra()
{
	int v,min,k, w, v1;
	int final[1001];
	for(v= 1; v <= M; v++)
	{
		final[v] = 0;
		D[v] = 65535;
	}
	k = Q;
	D[k] = 0;
	while(final[k] == 0)
	{
		final[k] = 1;
		for(v =0; v < g[k].size(); v++)
		{
			w = g[k][v].data;
			if(D[w] > D[k] + g[k][v].weight)
			{
				D[w] = D[k] + g[k][v].weight;
			}
		}
		min = 65535;
		for(v= 1; v <= M; v++)
		{
			if(D[v] < min && !final[v])
			{
				min = D[v];
				k = v;
			}
		}

	}

}

void create()
{
	int A, B, C,i;
	Node p;
	for(i =0; i < P; i++)
	{
		scanf("%d%d%d", &A, &B, &C);
		p.data = B;
		p.weight = C;
		g[A].push_back(p);
		p.data = A;
		p.weight = C;
		g[B].push_back(p);
	}
}
void init()
{
	int i;
	for(i = 1; i <= M; i++)
	{
		g[i].clear();
	}
}

int main()

{
	int i,j, T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d%d", &N, &M, &P,&Q);
		init();
		for(i = 0; i < N; i++)
		{
			scanf("%d", &j);
			team[i] = j;
		}
		create();
		shortestpath_dijstra();
		mini = D[team[0]];
		for(i = 1; i < N; i++)
		{
			if(D[team[i]] < mini)
				mini = D[team[i]];
		}
		printf("%d\n", mini);
	}
	return 0;
}
        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值