题意:中文题,不解释
策略:广搜。第一道广搜题,先从目标点开始,进队列,标记此节点已被找过,以对首为起始点再找与它相连(并且没有被标记的)的结点入队尾,删除队首,然后在以此时的队首为起始点,标记此节点已被找过, 找与它相邻的点(并且没有被标记的),删除队首,一直循环直至所有节点都被找完。
代码:
#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