多源单汇问题

《经典问题一》:

若有

  dist[t][j] 中 t 不是固定的,而j是固定的,我们只要将存储的边反一下,变成普通的单元汇的问题即可

 

《BFS解决的问题》

 1 Problem G. Guard the castle
 2 Input file: standard input
 3 Output file: standard output
 4 Time limit: 1 second
 5 Memory limit: 256 megabytes
 6 zzz 最近在玩一款"守卫城堡"塔防游戏。以下是游戏规则:沙盘上有n个城堡,敌方有m支小队分别潜藏
 7 在不同的城堡之中,单位时间每支小队可以移动到相邻的城堡(当然小队也可以选择不移动);敌方获
 8 得胜利的条件是,至少k支队伍汇集在同一城堡中。
 9 zzz 现在想知道,敌方获得胜利的最短时间,以便他继续DDL!
10 Input
11 第一行包含四个整数n, m, k, e(1 ≤ n ≤ 105
12 , 1 ≤ k ≤ m ≤ 10, n ≤ e ≤ 2 × 105
13 ),分别表示:城堡的数量,
14 敌方小队数量,k见题目描述,道路的数量。
15 第二行m个不同的整数,分别表示m支小队所在城堡的编号。
16 接下来e行,每行两个整数u, v(1 ≤ u, v ≤ n, u 6= v),表示城堡u和v之间有一条道路(可能会有重边)。
17 Output
18 一行一个整数表示敌方获得胜利的最短时间,若无法胜利则输出−121 6 4 4 6
22 1 4 5 6
23 1 3
24 2 3
25 2 5
26 3 4
27 3 5
28 5 6
29 2
30 6 4 1 6
31 1 4 5 6
32 1 3
33 2 3
34 2 5
35 3 4
36 3 5
37 5 6
38 0
39 5 2 2 3
40 2 5
41 1 2
42 1 3
43 4 5
44 -1
权重为1,BFS 的时间复杂度又在O(n)的情况下,不会超时;
基本思路是:
在各个城堡中的队伍同时起跑(BFS)(BFS能在同一时间的情况下向四周发散,相当于一个人能在同一时间内走到四周)
看一下那个点被走了k次以及k次以上,深度就是时间也就是答案
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <vector>
 5 #include <queue>
 6 using namespace std;
 7 const int N = 12, M = 1e5 + 10, INF = 0x3f3f3f3f;
 8 int n, m, k, e;
 9 int stapos[N], dep[N]; // stapos用来记录开始各个小队在的位置;//记录每一个小队到各个点的距离;
10 bool st[N];
11 vector<int> g[N];    //保存图
12 vector<int> cost[M]; //看一下点i被多少个队伍经过,且保存一下进过这个点用的时间;
13 void bfs(int x)
14 {
15     memset(st, false, sizeof(st));
16     memset(dep, 0, sizeof(dep));
17     queue<int> q;
18     q.push(x);
19     st[x] = true;
20     while (!q.empty())
21     {
22         int temp = q.front();
23         q.pop();
24         for (int node : g[temp])
25         {
26             if (!st[node])
27             {
28                 st[node] = true;
29                 dep[node] = dep[temp] + 1;
30                 cost[node].push_back(dep[node]);
31                 q.push(node);
32             }
33         }
34     }
35 }
36 int main()
37 {
38     cin >> n >> m >> k >> e;
39     for (int i = 1; i <= m; i++)
40         cin >> stapos[i];
41     int a, b;
42     for (int i = 1; i <= e; i++)
43     {
44         scanf("%d%d", &a, &b);
45         g[a].push_back(b), g[b].push_back(a);
46     }
47     for (int i = 1; i <= m; i++)
48     {
49         cost[stapos[i]].push_back(0);
50         bfs(stapos[i]);
51     }
52     int ans = INF;
53     for (int i = 1; i <= n; i++)
54     {
55         if (cost[i].size() >= k)
56         {
57             /* int temp=0,count=0;
58             for (int j:cost[i])
59             {
60                 temp=max(cost[i][j],temp);
61                 count++;
62                 if (count>=k) break;
63             }
64             ans=min(ans,temp); */
65             //上面写的太复杂,优化:
66             sort(cost[i].begin(), cost[i].end());
67             ans=min(ans,cost[i][k-1]);//因为vector是从0开始存储的,所以k-1;
68         }
69     }
70     if (ans == INF)
71         printf("-1\n");
72     else
73         printf("%d\n", ans);
74     return 0;
75 }

 

posted @ 2022-05-29 09:00  次林梦叶  阅读(32)  评论(0)    收藏  举报