HDU3938 Portal
来源:互联网 发布:php oa 开源 编辑:程序博客网 时间:2024/06/11 00:50
题意:
有n个点,给你m条无向边,然后有q次询问,每次询问给你一个L,问你对于u到v的所有路径中的每条路径中最长的边的最小值不超过L的这样的点对有多少。
思路:首先考虑每个点对,因为点对之间的决定值只是由最大边来决定。所以贪心一下,边按照从小到大连接,如果之前已经被连接了,那么后面没必要再连接了。
然后每次,询问跑一次是不现实的。嗯,因为大的情况一定包含比它小的情况,所以我们可以离线,排序,处理一次就可以。
判断连接自然就是并查集了。不过注意合并的时候,增加的点数是两棵树的点数的乘积。
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 1e4+5;const int inf = 1e9;int n,m,q;struct edge{ int u,v,w; bool operator < (const edge &a)const { return w < a.w; }}edge[MAXN*5];struct query{ int id; int key; bool operator < (const query &a)const { return key < a.key; }}query[MAXN];int ans[MAXN];int pre[MAXN];int findx(int x){ return pre[x] == x? x : pre[x] = findx(pre[x]);}int sum_point[MAXN];int connect(int u,int v){ u = findx(u); v = findx(v); int ans = 0; if(u != v) { ans = sum_point[u]*sum_point[v]; pre[v] = pre[u]; sum_point[u] += sum_point[v]; } return ans;}int main(){ while(~scanf("%d%d%d",&n,&m,&q)) { for(int i = 0; i < m; ++i) { scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); } for(int i = 0; i < q; ++i) { query[i].id = i; scanf("%d",&query[i].key); } sort(edge,edge+m); sort(query,query+q); for(int i = 1; i <= n; ++i) { pre[i] = i; sum_point[i] = 1; } int j = 0; int sum = 0; for(int i = 0; i < q; ++i) { while(j < m && edge[j].w <= query[i].key) { sum += connect(edge[j].u,edge[j].v); j++; } ans[query[i].id] = sum; } for(int i = 0;i < q; ++i)printf("%d\n",ans[i]); } return 0;}
阅读全文
0 0
- HDU3938 Portal
- hdu3938 Portal
- HDU3938 Portal
- hdu3938(Portal)并查集
- HDU3938 Portal 并查集
- portal
- Portal
- Portal
- portal
- Portal
- portal
- Portal
- Portal
- Portal
- portal
- portal
- HDU3938 并查集 并查集
- hdu3938(并查集+离线)
- UE4学习笔记21th:创建菜单控件蓝图
- 关于VMware下安装VMware tools,安装文件没有出现问题的解决
- 数据结构 图 Dijkstra算法
- 备份/etc文件的周期性任务的详细介绍
- source insight使用教程
- HDU3938 Portal
- django自定义非主键自增字段类型(auto increment field)
- UPC 1053 Mysterious Treasure (记忆化搜索)
- i = i++; in JAVA
- FreeSWITCH加载非默认模块
- hdu1404 博弈
- k近邻理论与实践
- UE4学习笔记22th:配置游戏模式
- 二叉树实例