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