解题思路
这是一道使用BFS解决的病毒传播问题,主要思路如下:
-
问题分析:
- 给定一个无向图
- 从某个起点
开始传播病毒
- 每天病毒会传播给相邻节点
- 给定
天后的感染结果
- 求所有可能的起始点
- 给定一个无向图
-
解决方案:
- 使用BFS模拟病毒传播过程
- 对每个点作为起点进行验证
- 记录每个点被感染的时间
- 比较最终结果与给定结果是否一致
-
关键点:
- 使用邻接表存储图
- BFS计算传播时间
- 注意输出格式(空格分隔,无行末空格)
代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 1005;
vector<int> graph[MAXN]; // 邻接表存储图
bool infected[MAXN]; // 最终感染状态
int infTime[MAXN]; // 感染时间
int n, m, k, t;
// BFS检查从起点v开始是否能得到给定结果
bool check(int v) {
fill(infTime, infTime + n + 1, 0);
queue<int> q;
q.push(v);
infTime[v] = 1; // 初始时间为1
while (!q.empty()) {
int curr = q.front();
q.pop();
if (infTime[curr] > t) break; // 超过时间t就停止
// 遍历相邻节点
for (int next : graph[curr]) {
if (infTime[next] == 0) { // 未访问过
infTime[next] = infTime[curr] + 1;
q.push(next);
}
}
}
// 验证结果
for (int i = 1; i <= n; i++) {
if ((infected[i] && infTime[i] == 0) ||
(!infected[i] && infTime[i] != 0)) {
return false;
}
}
return true;
}
int main() {
cin >> n >> m;
// 建图
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
// 读取感染结果
cin >> k >> t;
for (int i = 0; i < k; i++) {
int x;
cin >> x;
infected[x] = true;
}
// 检查每个点作为起点
vector<int> result;
for (int i = 1; i <= n; i++) {
if (check(i)) {
result.push_back(i);
}
}
// 输出结果
if (result.empty()) {
cout << "-1" << endl;
} else {
for (int i = 0; i < result.size(); i++) {
if (i > 0) cout << " ";
cout << result[i];
}
cout << endl;
}
return 0;
}
import java.util.*;
public class Main {
static final int MAXN = 1005;
static ArrayList<Integer>[] graph = new ArrayList[MAXN];
static boolean[] infected = new boolean[MAXN];
static int[] infTime = new int[MAXN];
static int n, m, k, t;
// BFS检查从起点v开始是否能得到给定结果
static boolean check(int v) {
Arrays.fill(infTime, 0);
Queue<Integer> q = new LinkedList<>();
q.offer(v);
infTime[v] = 1; // 初始时间为1
while (!q.isEmpty()) {
int curr = q.poll();
if (infTime[curr] > t) break; // 超过时间t就停止
// 遍历相邻节点
for (int next : graph[curr]) {
if (infTime[next] == 0) { // 未访问过
infTime[next] = infTime[curr] + 1;
q.offer(next);
}
}
}
// 验证结果
for (int i = 1; i <= n; i++) {
if ((infected[i] && infTime[i] == 0) ||
(!infected[i] && infTime[i] != 0)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
// 初始化图
for (int i = 0; i < MAXN; i++) {
graph[i] = new ArrayList<>();
}
// 建图
for (int i = 0; i < m; i++) {
int u = sc.nextInt();
int v = sc.nextInt();
graph[u].add(v);
graph[v].add(u);
}
// 读取感染结果
k = sc.nextInt();
t = sc.nextInt();
for (int i = 0; i < k; i++) {
infected[sc.nextInt()] = true;
}
// 检查每个点作为起点
ArrayList<Integer> result = new ArrayList<>();
for (int i = 1; i <= n; i++) {
if (check(i)) {
result.add(i);
}
}
// 输出结果
if (result.isEmpty()) {
System.out.println("-1");
} else {
for (int i = 0; i < result.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(result.get(i));
}
System.out.println();
}
}
}
from collections import defaultdict, deque
from typing import List, Set
def check(v: int, graph: defaultdict, infected: Set[int], n: int, t: int) -> bool:
"""BFS检查从起点v开始是否能得到给定结果"""
inf_time = [0] * (n + 1)
q = deque([v])
inf_time[v] = 1 # 初始时间为1
while q:
curr = q.popleft()
if inf_time[curr] > t: # 超过时间t就停止
break
# 遍历相邻节点
for next_node in graph[curr]:
if inf_time[next_node] == 0: # 未访问过
inf_time[next_node] = inf_time[curr] + 1
q.append(next_node)
# 验证结果
for i in range(1, n + 1):
if (i in infected and inf_time[i] == 0) or \
(i not in infected and inf_time[i] != 0):
return False
return True
def main():
# 读取图的基本信息
n, m = map(int, input().split())
# 建图
graph = defaultdict(list)
for _ in range(m):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
# 读取感染结果
k, t = map(int, input().split())
infected = set(map(int, input().split()))
# 检查每个点作为起点
result = []
for i in range(1, n + 1):
if check(i, graph, infected, n, t):
result.append(i)
# 输出结果
if not result:
print("-1")
else:
print(" ".join(map(str, result)))
if __name__ == "__main__":
main()
算法及复杂度
- 算法:BFS(广度优先搜索)
- 时间复杂度:
- 需要对每个点进行BFS
- 空间复杂度:
- 需要存储图和访问数组