并查集+二分-hdu-4750-Count The Pairs
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4750
题目大意:
给一无向图,n个点,m条边,每条边有个长度,且不一样。定义f(i,j)表示从节点i到节点j的所有路径中的最大边权值的最小值。有q个询问,每个询问有个t,求f(i,j)>=t的种数。
解题思路:
并查集+简单dp+二分。
比赛的时候各种TLE和MLE。只是查找方式不对。
队友思路,先按边从小到大排序考虑,对于每条边E该边两个节点为a、b,如果a、b不在同一个联通块,则a联通块中点集A和b联通块中点集B的f值一定为E(因为E升序)。恰好能使其通路。
map[i]表示以权值为i的边作为f值的点对个数。
sum[i]表示以大于等于第i大边权值的权值作为f值得点对总的个数。
对于每一个t,在排序了的sig[i](能取的边权值)中二分找到大于等于它的最小的小标j。输出sum[j]即可。
注意:
求点对个数时要乘以2.
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3fffffff
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 11000
#define Maxm 510000
struct Edge
{
int a,b,c;
}edge[Maxm];
map<int,int>myp; short int fa[Maxn],num[Maxn];
int n,m;
int sum[Maxm],sig[Maxm]; bool cmp(struct Edge aa,struct Edge bb)
{
return aa.c<bb.c; //对边排序
} int find(int x) //并查集 路径压缩
{
int tmp=x; while(x!=fa[x])
x=fa[x]; while(fa[tmp]!=x)
{
int tt=fa[tmp];
fa[tmp]=x;
tmp=tt;
}
return x;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m))
{
int a,b,c;
myp.clear(); for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[i].a=a,edge[i].b=b,edge[i].c=c;
sig[i]=c;
}
sort(edge+1,edge+m+1,cmp);
for(int i=0;i<=n;i++)
{
fa[i]=i;
num[i]=1; //以i为根的联通块点的个数
}
for(int i=1;i<=m;i++)
{
int ra=find(edge[i].a);
int rb=find(edge[i].b);
if(ra!=rb) //不在一个联通块内,两个块内的点通过该边连接,f值为该边
{
if(myp.find(edge[i].c)!=myp.end())
myp[edge[i].c]=myp[edge[i].c]+num[ra]*num[rb]*2;
else
myp[edge[i].c]=num[ra]*num[rb]*2;
fa[rb]=ra; //合并
num[ra]+=num[rb];
}
}
int q;
scanf("%d",&q);
sort(sig+1,sig+m+1); //对边权值排序
memset(sum,0,sizeof(sum));//sum[i]表示以大于等于第i大边权值的权值作为f值得点对总的个数。
sum[m]=myp[sig[m]];
for(int i=m-1;i>=1;i--)
sum[i]+=sum[i+1]+myp[sig[i]];
for(int i=1;i<=q;i++)
{
int tt;
scanf("%d",&tt);
int pos=lower_bound(sig+1,sig+m+1,tt)-sig;//二分查找位置
printf("%d\n",sum[pos]); } }
return 0;
}
并查集+二分-hdu-4750-Count The Pairs的更多相关文章
- hdu 4750 Count The Pairs(并查集+二分)
Problem Description With the 60th anniversary celebration of Nanjing University of Science and Techn ...
- HDU 4750 Count The Pairs (2013南京网络赛1003题,并查集)
Count The Pairs Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- HDU 4750 Count The Pairs ★(图+并查集+树状数组)
题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...
- 2013南京网赛1003 hdu 4750 Count The Pairs
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意:给出一个无向图,f(a,b)表示从点a到点b的所有路径中的每条路径的最长边中的最小值,给出 ...
- hdu 4750 Count The Pairs(并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4750 代码: #include<cstdio> #include<cstring&g ...
- HDU 4750 Count The Pairs(并查集)
题目链接 没有发现那个点,无奈. #include <cstdio> #include <cstring> #include <cmath> #include &l ...
- HDU 4750 Count The Pairs (离线并查集)
按边从小到大排序. 对于每条边(from, to, dist),如果from和to在同一个集合中,那么这条边无意义,因为之前肯定有比它更小的边连接了from和to. 如果from和to不属于同一个集合 ...
- [2013 ACM/ICPC Asia Regional Nanjing Online C][hdu 4750]Count The Pairs(kruskal + 二分)
http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意: 定义f(u,v)为u到v每条路径上的最大边的最小值..现在有一些询问..问f(u,v)>=t ...
- hdu 4750 Count The Pairs (2013南京网络赛)
n个点m条无向边的图,对于q个询问,每次查询点对间最小瓶颈路 >=f 的点对有多少. 最小瓶颈路显然在kruskal求得的MST上.而输入保证所有边权唯一,也就是说f[i][j]肯定唯一了. 拿 ...
- HDU 5441——Travel——————【并查集+二分查界限】
Travel Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Su ...
随机推荐
- 如何实现 iOS 自定义状态栏
给大家介绍如何实现 iOS 自定义状态栏 Sample Code: 01 UIWindow * statusWindow = [[UIWindow alloc] initWithFrame:[UIAp ...
- RDBMS 数据库补丁集补丁号码高速參考-文档 ID 1577380.1
保存此文,高速查询补丁号 Oracle Database - Enterprise Edition - 版本号 8.1.7.0 和更高版本号 本文档所含信息适用于全部平台 补丁集/PSU 补丁号码 ...
- sqlserver中几种典型的等待
为了准备今年的双11很久没有更新blog,在最近的几次sqlserver问题的排查中,总结了sqlserver几种典型的等待类型,类似于oracle中的等待事件,如果看到这样的等待类型时候能够迅速定位 ...
- [Protractor] Use protractor to catch errors in the console
For any reason, there is an error in your code, maybe something like undefined error. Protractor sti ...
- win下 git gui 使用教程
现在很多都有git来托管项目或者来查找资料,但是看起来操作不是很方便,现在由于win下可以直接使用git gui,让使用git变得方便,当然这只是针对日常简单的使用,如果想详细的使用,可以去参考廖学峰 ...
- [core Java学习笔记][第一二三章基本语法]
基本语法 1 Java 简单的类型 1.1 一些常量 正无穷大 Double.POSITVE_INFINITY 负无穷大 Double.NEGATIVE_INFINITY 不存在 Double.NaN ...
- photoshop动作面板批量处理图片边框技巧
1,想给图片加上边框,在不改变图片大小的前提下,可以这样做:ctrl+a,全选图片,然后“编辑”-----“描边”,在跳出来的选项卡里面可以设置边框颜色,大小,位置,及混合模式, ,我们设置好了,就可 ...
- JS 事件对象和事件冒泡
1.事件对象 js的事件对象中保存了当前被触发事件的一些相关的属性信息,如事件源.事件发生时的鼠标位置.事件按键等. 事件对象的获取方法: IE中可以window.event直接获取,而Firefox ...
- Cisco cmd 命令
1.enable 开启全局配置模式:disable 禁用配置模式 2.config进入配置模式 3.line 设置进入用户模式密码:分为 line aux 0;line console 0;line ...
- 看到的一些js小知识
向数组结尾添加元素高效方法: var arr = [1,2,3]; arr[arr.length] = 4 头部: var a = [1,2,3]; a.concat(4,5); // 1,2,3,4 ...