HDU 4750 Count The Pairs ★(图+并查集+树状数组)
题意
给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值。Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, t] >= t((s,t)和(t,s)是两对)
思路
按边权从小到大排序。考虑从小到大往图中加边同时计算以加入的边为f值的点对数。
难点和重点在于用并查集维护边的连通情况。
对于新加入的边(u, v),如果u,v原来便连通,则没有以该边为f值的点对,因为它一定不是最小边。
而如果(u, v)不连通,就可以把这条边能到达的点分为和u连通以及和v连通(分别和u、v在同一并查集中),那么分别从u、 v的连通集中取一个点组成的点对的f值都是这条边,即答案 = 2 * |Union(u)| * |Union(v)|。所以并查集还需要维护各自集中的点个数。
最后用树状数组维护一下前缀和,询问的时候二分+查询前缀和即可。
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, end) for (int i = begin; i <= end; i ++)
using namespace std;
const int MAX = 500005;
struct BIT{
int t[MAX<<1];
int bound;
inline void init(int n){
bound = n;
MEM(t, 0);
}
//lowbit(x):求2^q, q是x二进制最右边的1的位置.
inline int lowbit(int x){
return x & (-x);
}
inline void update(int x, int v){
for (int i = x; i <= bound; i += lowbit(i))
t[i] += v;
}
inline int sum(int x){
int res = 0;
for (int i = x; i >= 1; i -= lowbit(i))
res += t[i];
return res;
}
}bit;
const int MAXN = 10005;
struct Disjoint_Sets{
struct Sets{
int father, ranks, num;
}S[MAXN];
inline void Init(int n){
for (int i = 0; i <= n; i ++){
S[i].father = i;
S[i].ranks = 0;
S[i].num = 1;
}
}
inline int Father(int x){
if (S[x].father == x){
return x;
}
else{
S[x].father = Father(S[x].father); //Path compression
return S[x].father;
}
}
inline bool Union(int x, int y){
int fx = Father(x), fy = Father(y);
if (fx == fy){
return false;
}
else{ //Rank merge
int num1 = S[fx].num, num2 = S[fy].num;
if (S[fx].ranks > S[fy].ranks){
S[fy].father = fx;
}
else{
S[fx].father = fy;
if (S[fx].ranks == S[fy].ranks){
++ S[fy].ranks;
}
}
S[Father(fx)].num = num1+num2;
return true;
}
}
}DS;
struct que{
int t, res;
}q[100005];
struct edges{
int u, v, w;
}e[500005];
bool cmp(edges n1, edges n2){
return n1.w < n2.w;
}
vector <int> adj[10005];
int main(){
int n, m;
while(scanf("%d %d", &n, &m) != EOF){
for (int i = 0; i < m; i ++) scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
sort(e, e+m, cmp);
int Q;
scanf("%d", &Q);
for (int i = 0; i < Q; i ++){
scanf("%d", &q[i].t);
q[i].res = 0;
}
for (int i = 0; i <= n; i ++) adj[i].clear();
DS.Init(n);
bit.init(m);
for (int i = 0; i < m; i ++){
if (DS.Father(e[i].u) != DS.Father(e[i].v)){
bit.update(m - i, 2*DS.S[DS.Father(e[i].u)].num*DS.S[DS.Father(e[i].v)].num);
DS.Union(e[i].u, e[i].v);
}
}
for (int i = 0; i < Q; i ++){
int t = q[i].t;
int l = 0, r = m - 1;
while(l < r){
int mid = MID(l, r);
if (e[mid].w < t){
l = mid + 1;
}
else{
r = mid;
}
}
while (l < m && e[l].w < t) l ++;
printf("%d\n", bit.sum(m - l));
}
}
return 0;
}
[/cpp]
HDU 4750 Count The Pairs ★(图+并查集+树状数组)的更多相关文章
- HDU 4750 Count The Pairs (离线并查集)
按边从小到大排序. 对于每条边(from, to, dist),如果from和to在同一个集合中,那么这条边无意义,因为之前肯定有比它更小的边连接了from和to. 如果from和to不属于同一个集合 ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- BZOJ-3211花神游历各国 并查集+树状数组
一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...
- BZOJ3211 花神游历各国 并查集 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...
- 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
- Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)
题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- la4730(并查集+树状数组)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=30& ...
- 【BZOJ3211】花神游历各国 并查集+树状数组
[BZOJ3211]花神游历各国 Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 41 100 5 551 1 22 1 ...
随机推荐
- django连接mongodb mongoengine
优点 MongoEngine (http://mongoengine.org)1. 提供了和 Django 原生 ORM 几乎一样的一切,功能已经相当强大;2. 用起来比 Django 原生 ORM ...
- Linux系统——shell脚本应用示例
传入一个网段地址,自动找出本网段内存活的IP地址.2,将存活的IP地址当作密码来创建Linux用户,用户名格式为:你的名字_数字 3,有几个存活IP地址,就自动创建几个用户 4,最后将创建的用户名 ...
- XDU 1130 (快速幂)
题目大意:原题链接 解题思路:sum((p+i*d)*C(n,i))=sum(p*C(n,i)+d*i*C(n,i)) ; 又因为i*C(n,i)=n*C(n-1,i-1) 所以sum((p+i*d) ...
- HTTP服务器(3)
功能完整的HTTP服务器 导语 这个一个功能完备的HTTP服务器.它可以提供一个完整的文档输,包括图像,applet,HTML文件,文本文件.它与SingleFileHttpServer非常相似,只不 ...
- react build 后打包发布总结
一,部署在apache web服务器上(wamp | xammp) 1.后台接口需要做跨域设置 (1)在服务端利用Access-Control-Allow-Origin响应头解决. 设置A ...
- zookeeper 监听事件 NodeCacheListener
zookeeper 监听事件 NodeCacheListener NodeCacheListener一次注册,每次监听,但是监听不到操作类型,不知道是增加?删除?还是修改? 1.测试类: packag ...
- java 与C# 时间格式 交互
方法一 C#端代码 IsoDateTimeConverter convert = new IsoDateTimeConverter(); string ret = JsonConvert.Serial ...
- Django---ModelForm详解
示例: from django.db import models from django.forms import ModelForm TITLE_CHOICES = ( ('MR', 'Mr.'), ...
- 20145216史婧瑶《Java程序设计》第3周学习总结
20145216 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 4.1 类与对象 •对象(Object):存在的具体实体,具有明确的状态和行为 •类(Class) ...
- 20145328 《Java程序设计》第1周学习总结
20145328 <Java程序设计>第1周学习总结 教材学习内容总结 了解Java基础知识 1995年5月23日,Java诞生,JDK 1.0a2发布 Java约以两年为周期推出重大版本 ...