(最小生成树(并查集加边法))2015网选,hdu5441 Travel
来源:互联网 发布:js 数字相加 编辑:程序博客网 时间:2024/06/01 08:38
/*题目:1005.Travel链接:http://acm.hdu.edu.cn/showproblem.php?pid=5441题目大意:给出n个顶点、m条边、k个x值,每条边有相应的权值;对每个x值,求只借助权值<=x的边而连通的顶点对有多少对?分析:最小生成树(并查集加边法)。 只需求一遍最小生成树,O(m)。 因为求解答案时,处理较大的x可以利用处理完较小的x留下的图(最小生成树的零碎部分),故将边按权值排序依次进行加边,将x从小到大排序依次处理。 对于当前x,加边加到权值>x的时候就不加了;处理下一个更大的x时,再继续在上一次停下的位置继续加。 答案利用求最小生成树的中间结果解。利用并查集记录以结点v为代表的结点集合的结点个数,则每加一条边{x,y},ans = ans - (root[x] * (root[x] - 1) + root[y] * (root[y] - 1)) + root[xy] * (root[xy] - 1); 优化:当已经得到一棵最小生成树时,便任意两点均连通,剩下的边都可以不处理。ps:只用并查集也可以,貌似用最小生成树的好处就只有那个优化。*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <set>#include <queue>#include <map>#include <algorithm>using namespace std;#define mem(x,i) memset(x,i,sizeof(x))#define sfi(a) scanf("%d", &a) #define sfii(a,b) scanf("%d %d", &a, &b) #define sfiii(a,b,c)scanf("%d %d %d", &a, &b, &c) const double EPS = 1e-10;const double pai = acos(-1.0);const int INF = 0xfffffff;const int MOD = 1000000007;typedef long long LL;const int maxq = 5000 + 5;struct Edge{ int u, v, w; Edge(int u, int v, int w) :u(u), v(v), w(w){} bool operator < (const Edge& e)const{ return w < e.w; }};const int max_node = 20000 + 5;int root[max_node];struct UFS{ int S[max_node]; void init(int n){ for (int i = 1; i <= n; i++){ S[i] = i; root[i] = 1; } } int findset(int x){ return S[x] == x ? x : S[x] = findset(S[x]); } int merge(int x, int y){ return S[x] = y; }}ufs;struct MST{ bool Kruskal(int &cnt, vector<Edge> &e,int &st, int x,int &ret){ if (cnt <= 1)return true; for (int i = st; i < e.size(); i++){ if (e[i].w>x) return false; st = i; int x = ufs.findset(e[i].u); int y = ufs.findset(e[i].v); if (x != y){ ret -= (root[x] * (root[x] - 1) + root[y] * (root[y] - 1)); int xy = ufs.merge(x, y); root[xy] = root[x] + root[y]; ret += root[xy] * (root[xy] - 1); if (--cnt == 1)return true; } } return false; }}mst;struct NODE{ int no, x; bool operator <(const NODE &b)const{ return x < b.x; } NODE(int x, int no) :x(x), no(no){}};vector<Edge> e;vector<NODE> x;int ans[maxq];int N, M, Q, X;int main(){ //freopen("f:\\input.txt", "r", stdin); int T; sfi(T); while (T--){ sfiii(N, M, Q); e.clear(); x.clear(); ufs.init(N); for (int i = 0; i < M; i++){ int u, v, w; sfiii(u, v, w); e.push_back(Edge(u, v, w)); } sort(e.begin(), e.end()); for (int i = 1; i <= Q; i++){ sfi(X); x.push_back(NODE(X, i)); } sort(x.begin(), x.end()); int st = 0, ret = 0, cnt = N; for (int i = 0; i < x.size(); i++){ if (!mst.Kruskal(cnt, e, st, x[i].x, ret)) ans[x[i].no] = ret; else ans[x[i].no] = N*(N - 1); } for (int i = 1; i <= Q; i++){ printf("%d\n", ans[i]); } } return 0;}
0 0
- (最小生成树(并查集加边法))2015网选,hdu5441 Travel
- HDU5441 Travel 并查集
- HDU5441 Travel 并查集
- HDU5441 Travel (2015年长春网络赛,并查集)
- Regional Changchun Online--Travel(最小生成树&& 并查集)
- 离线+并查集 hdu5441 Travel
- HDU5441 Travel 有秩并查集
- HDU5441 Travel
- hdu5441 Travel
- HDU5441(2015长春网赛)——Travel(并查集应用,离线处理)
- uva 10816 - Travel in Desert(最小瓶颈生成树+最短路)
- uva 10816 Travel in Desert (最小生成树 + 最短路)
- UVA 10816 - Travel in Desert(最小生成树+最短路)
- HDU5441 并查集+(按大小)预处理
- hdu5441 并查集(两种方法)
- 最小生成树(并查集)
- 最小生成树(并查集)
- 并查集(最小生成树)
- Android中Activity切换时共享视图元素的切换动画(4.x兼容方案)
- U盘安装Ubuntu Server ,CD-ROM自检,安装失败
- Oracle分析函数系列之first_value/last_value:在记录集中查找第一条记录和最后一条记录
- Ubuntu adb no permissions
- java匿名内部类详解
- (最小生成树(并查集加边法))2015网选,hdu5441 Travel
- Algorithms—40.Combination Sum II
- SQL中的空值NULL
- Socket模型详解
- 我们前端是怎么找到工作的
- makefile 分析
- Android中的搜索框(SearchView)的功能和用法
- 集团信息化之路 人力资源系统的漫长之路刚刚起步
- OC学习之Runtime之一类与对象