#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LL long long #define UIT unsigned int #define DB double #define PII pair #define MKPR(a, b) make_pair(a, b) #define MMST(a) memset(a, 0, sizeof(a)) #define PB push_back #define FOR(i, beg, ed, s) for (int i = beg; i < ed; i += s) #define FORE(i, beg, ed, s) for (int i = beg; i <= ed; i += s) #define LOOP while (true) #define IN scanf #define OUT printf using namespace std; vector f; vector a; vector> mp; vector vis; //比较函数 bool cmp(const PII& a, const PII& b) { if (a.first == b.first) { return a.second < b.second; } return a.first > b.first; //只写这一句也可 } //并查集标准函数 int find(int x) { int r = x; while (r != f[r]) { r = f[r]; } int t = x; int tmp = 0; while (t != tmp) { tmp = f[t]; f[t] = r; t = tmp; } return r; } void uni_set(int x, int y) { int xx = find(x); int yy = find(y); if (xx != yy) { f[xx] = yy; } } void solve() { int t = 0, m = 0, n = 0; int x = 0, y = 0; int cnt = 0; LL ans = 0; IN("%d", &t); while (t--) { IN("%d%d", &n, &m); f.resize(n + 1); mp.resize(n + 1); a.resize(n + 1); vis.resize(n + 1); FORE(i, 1, n, 1) { IN("%d", &a[i].first); a[i].second = i; mp[i].clear(); f[i] = i; vis[i] = false; } //排序,按权值从大到小 sort(a.begin() + 1, a.end(), cmp); a.PB(MKPR(0, 0)); ans = 0; cnt = 0; //建图,邻接表 while (m--) { IN("%d%d", &x, &y); mp[x].PB(y); mp[y].PB(x); } FORE(i, 1, n, 1) { cnt++; //连通块个数先加一,即假设当前点是一个独立点 vis[a[i].second] = true; //已访问 //遍历该点的邻接点 for (auto it : mp[a[i].second]) { if (vis[it]) { //若邻接点在当前点之前被访问过(两个点相连) if (find(it) != find(a[i].second)) { cnt--; //那么连通块个数减一 //加入并查集 uni_set(it, a[i].second); } } } //更新答案 ans += 1LL * cnt * (a[i].first - a[i + 1].first); } OUT("%lldn", ans); } } int main(void) { solve(); return 0; }
上一篇 SpringMVC-@RequestMapping
下一篇 Python升级之路(五) 函数
版权所有 (c)2021-2022 MSHXW.COM
ICP备案号:晋ICP备2021003244-6号