1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > PAT1034 Head of a Gang (30)(并查集)

PAT1034 Head of a Gang (30)(并查集)

时间:2022-12-07 12:39:56

相关推荐

PAT1034 Head of a Gang (30)(并查集)

题意:

给出n次通话记录,当通话的人数超过2人并且通话总时长超过k时,这些人就是犯罪团伙,其中通话时间最大的人是头目,要求按字母序输出头目和团伙人数

思路:

就是并查集,将两两通话的人关联在一起,因为通话的人的姓名是按三位字母给出的,所以要离散化,并且对应要用一些STL保存映射。我自己写的时候有两个点没过,后来改过了,错误原因写在下面注释里了。网上的代码也有用DFS找连通分量做的。

#include<iostream>#include<string>#include<vector>#include<map>#include<set>#include<algorithm>using namespace std;const int INF = 0xfffff;const int maxn = ;//这里开1005会出现段错误,因为是n个通话可能有2n个人map<string, int> gang;map<int, string> gangName;int gangTime[maxn];int p[maxn];int n, k,pos=0;vector<int> head[maxn];set<string> res;void init() {for (int i = 0; i < maxn; i++) {p[i] = i;head[i].push_back(i);}}int find(int x) {if (x == p[x]) return x;return p[x] = find(p[x]);}void merge(int x, int y) {x = find(x);y = find(y);if (x != y) {p[x] = y;for (auto i = head[x].begin(); i != head[x].end(); i++) {head[y].push_back(*i);}head[x].clear();//这里必须清零}}int main() {scanf("%d%d", &n, &k);init();for (int i = 0; i < n; i++) {string name1, name2;int time;cin >> name1 >> name2 >> time;if (gang.find(name1) == gang.end()) {gang[name1] = pos;gangName[pos++] = name1;}if (gang.find(name2) == gang.end()) {gang[name2] = pos;gangName[pos++] = name2;}gangTime[gang[name1]] += time;gangTime[gang[name2]] += time;merge(gang[name1], gang[name2]);}for (int i = 0; i < pos; i++) {if (head[i].size() > 2) {int maxTime = -1, index;int totalTime = 0;for (auto x : head[i]) {if (maxTime < gangTime[x]) {maxTime = gangTime[x];index = x;}totalTime += gangTime[x];}if (totalTime > 2*k) {res.insert(gangName[index]);}}}if (res.empty())cout << 0 << endl;else {cout << res.size() << endl;for (auto x : res) {int h = find(gang[x]);cout << x << " " << head[h].size() << endl;}}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。