X Distance 搜索或并查集
来源:互联网 发布:真正的绝望是什么知乎 编辑:程序博客网 时间:2024/05/21 22:31
题目大意
给你一个带权无向图, n个节点, m条边, 一个节点到另一个节点的路径的cost等于路径上所有边权值的最大值, 求有多少对节点路径cost等于X
思路
有两种解法, 一种利用搜索
去掉所有权值大于x的边, 搜索所有联通块, 每个联通块中两两节点之间的cost一定小于x(大于x的边已经去掉了), 所以这个联通块中有a个节点, 那么有a*(a-1)/2对节点cost小于x, 将所有联通图中节点对数加起来就可以得到cost小于等于x的节点对数
同理去掉大于x-1的边, 就可以求出cost小于x-1的节点对数
将两个数值相减就可以得到cost等于x的节点对数另一种解法利用并查集
将所有边按权值大小从小到达排序, 排序是为了保证当开始处理权值等于x的边时, 所有权值小于x的边已经连接起来了
记录每个并查集的节点个数, 如果边的权值小于等于x, 并且边的两个节点不在一个并查集里面, 就将它们连起来, 如果这条边的权值刚好等于x, 那么两个并查集中的节点相互连接的cost一定等于x, 那么答案个数增加size(a)*size(b)(两个并查集节点个数乘积
代码
- 搜索
Language: C++
CPU Time usage: 204 ms
Memory usage: 9020 KB
Source code: 1361 bytes
#include <bits/stdc++.h>using namespace std;const int MAXN = 1E5 + 100;int n, m, x, a, b, c;typedef pair<int, int> P;vector<P> v[MAXN];bool vis[MAXN];long long cnt(int ma){ long long ret = 0; memset(vis, 0, sizeof(bool)*(n+10)); for(int i=1; i<=n; ++i) { if(!vis[i]) { long long cnt = 1; vis[i] = 1; queue<int> que; que.push(i); int now, nxt; while(!que.empty()) { now = que.front(); que.pop(); for(int i=0; i<(int)v[now].size(); ++i) { nxt = v[now][i].first; if(vis[nxt] == 0 && v[now][i].second <= ma) { ++cnt; vis[nxt] = 1; que.push(nxt); } } } //cout << i << " " << cnt <<endl; ret += cnt*(cnt-1)/2; } } return ret;}int main(){ ios_base :: sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n >> m >> x; for(int i=0; i<m; ++i) { cin >> a >> b >> c; v[a].push_back({b, c}); v[b].push_back({a, c}); } cout << cnt(x) - cnt(x-1) << endl; return 0;}
- 并查集
Language: C++
CPU Time usage: 66 ms
Memory usage: 3916 KB
Source code: 1358 bytes
#include <bits/stdc++.h>using namespace std;int a, b, w, n, m, x;const int MAXN = 1E5 + 100;int par[MAXN], rk[MAXN], sz[MAXN];void init(int n){ for(int i=1; i<=n; ++i) { par[i] = i; rk[i] = 0; sz[i] = 1; }}int find(int x){ return par[x] == x ? x : x = find(par[x]);}bool same(int x, int y){ return find(x) == find(y);}void unite(int x, int y){ x = find(x); y = find(y); if(x == y) return ; if(rk[x] < rk[y]) { par[x] = y; sz[y] += sz[x]; } else { par[y] = x; sz[x] += sz[y]; if(rk[x] == rk[y]) ++rk[x]; }}struct edge{ int x, y, cost; bool operator<(const edge & e) const { return cost < e.cost; }};edge es[MAXN*3];int main(){ ios_base :: sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n >> m >> x; init(n); for(int i=0; i<m; ++i) cin >> es[i].x >> es[i].y >> es[i].cost; sort(es, es+m); long long ans = 0; for(int i=0; i<m; ++i) { if(es[i].cost>x) break; if(!same(es[i].x, es[i].y)) { if(es[i].cost == x) ans += 1ll*sz[find(es[i].x)]*sz[find(es[i].y)]; unite(es[i].x, es[i].y); } } cout << ans << endl; return 0;}
阅读全文
0 0
- X Distance 搜索或并查集
- CS 300 X Distance 思维+并查集
- Hduoj1241【搜索 或 并查集】
- HDU1181 变形课(搜索或并查集)
- hdu 1198 Farm Irrigation (搜索或并查集)
- HDU3926Hand in Hand(搜索 或 并查集)
- 【离散化\并查集\搜索】cake
- Hdu1829 并查集+广度优先搜索
- 二叉搜索树 并查集
- HDU-4707-Pet【并查集】【搜索】
- Supermarket 并查集或贪心
- HDU1598 并查集 或 二分+DFS
- UVALive 4487 异或 并查集
- 并查集或图floyd-2
- LA 3644 - X-Plosives,并查集
- LA 3644 X-Plosives / 并查集
- UVa 1160 X-Plosives (并查集)
- UVa 1160 X-Plosives(并查集)
- [bigdata-085] centos 上 用screen
- 红黑树
- find命令进阶(三):xargs
- UBUNTU将新路径添加到ROS_PACKAGE_PATH中。
- HDU2544-最短路(dij堆优化与spfa)
- X Distance 搜索或并查集
- FastDFS之——集群的安装、 配置、 使用
- 搜索算法_PROBLEM
- 06 我的闲适音乐
- Android studio使用JNI全解析(二)
- Redis和Memcached的区别
- (JAVA)日期计算 -201509-2
- 安装Mysql5.7并修改初始密码
- C++(qt)游戏实战项目:坦克大战(三)