首页 > 代码库 > nyoj 115 城市平乱 【BFS】

nyoj 115 城市平乱 【BFS】

题意:中文题,不解释

策略:广搜。第一道广搜题,先从目标点开始,进队列,标记此节点已被找过,以对首为起始点再找与它相连(并且没有被标记的)的结点入队尾,删除队首,然后在以此时的队首为起始点,标记此节点已被找过, 找与它相邻的点(并且没有被标记的),删除队首,一直循环直至所有节点都被找完。

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#define MAXN 0x3f3f3f3f
using std::queue;
int map[1005][1005];  //储存两个城市来回的时间
bool vis[1005];
struct node{
	int isarmy;//标记该城市有没有军队
	int time; //到每个城市的时间
}armys[1005]; 
int bfs(int m, int Q)
{
	queue<int> q;
	int sum = MAXN;
	memset(vis, 0, sizeof(vis)); //标记几点有没有被搜索过
	q.push(Q); //从目标开始
	vis[Q] = 1;
	int temp; //当前的队首
	while(!q.empty()){
		temp = q.front();
		for(int i = 1; i <= m; i ++){
			if(!vis[i]&&map[temp][i]){
				armys[i].time += map[temp][i] + armys[temp].time;
				vis[i] = 1;
				q.push(i);
				if(armys[i].isarmy&&armys[i].time < sum) sum = armys[i].time; //判断是否有军队到达并且时间最少
			}
		}
		q.pop();
	}
	return sum;
}
int main()
{
	int t, n, m, q, p, i, j;
	scanf("%d", &t);
	while(t --){
		scanf("%d%d%d%d", &n, &m, &p, &q);
		memset(armys, 0, sizeof(armys));
		memset(map, 0, sizeof(map));
		int temp;
		for(i = 0; i < n; i ++){
			scanf("%d", &temp);
			armys[temp].isarmy = 1;
		}
		int a, b, c;
		for(i = 0; i < p; i ++){
			scanf("%d%d%d", &a, &b, &c);
			if(map[a][b] > c||!map[a][b]){
				map[a][b] = map[b][a] = c;
			}
		}
		int ans;
		ans = bfs(m, q);
		printf("%d\n", ans);
	}
	return 0;
}
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=115