并查集。
新兵入伍。三种操作:①入伍②合并队伍③查找一个队伍里面战斗力最弱的。注意队伍编号从0开始。
多了一个记录每个集合最小值的minn数组而已,然后判断的时候小心一点就可以了。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define maxn 200000 + 10 #define inf 0x3f3f3f3f int father[maxn]; int minn[maxn]; int Find(int x){ return father[x] == x ? x : father[x] = Find(father[x]); } int n, k, m; int main() { while (~scanf("%d %d %d", &n, &k, &m)) { for (int i = 0; i < n; i++) { father[i] = i; minn[i] = inf; } int ans = 0; for (int i = 0; i < k; i++) { int belong; int val; scanf("%d %d", &val, &belong); minn[belong] = min(minn[belong], val); } for (int i = 0; i < m; i++) { char s[10]; scanf("%s", s); if (s[0] == 'G') { int temp; scanf("%d", &temp); if (father[temp] == temp) { if (minn[temp] != inf) printf("Lowest rate: %d. ", minn[temp]); else printf("Company %d is empty. ", temp); } else { int belong = Find(temp); printf("Company %d is a part of company %d. ", temp, belong); } } else if (s[0] == 'M') { int x, y; scanf("%d %d", &x, &y); if (x == y) { puts("Reject"); continue; } if (father[x] == x && father[y] == y) { father[y] = x; minn[x] = min(minn[x], minn[y]); puts("Accept"); } else puts("Reject"); } else if (s[0] == 'A') { int val, belong; scanf("%d %d", &val, &belong); if (father[belong] != belong) { puts("Reject"); continue; } minn[belong] = min(minn[belong], val); puts("Accept"); } } printf(" "); } return 0; }