hdu 4750 Count The Pairs (2013南京网络赛)
n个点m条无向边的图,对于q个询问,每次查询点对间最小瓶颈路 >=f 的点对有多少。
最小瓶颈路显然在kruskal求得的MST上。而输入保证所有边权唯一,也就是说f[i][j]肯定唯一了。
拿到这题第一反映是用次小生成树的prim算法在求MST的同时求出每对点对的瓶颈路。几乎就是一个模板题,无奈却MLE。。。
于是换算法,用kruskal求MST,然后对于MST,离线LCA求出所有点对的瓶颈路。同UVA 11354 Bond(MST + LCA)然后剩下的就是读入&二分查找输出了。。无奈还是MLE!!!
最后。。。反思了一下。。。在kruskal的过程,当前加入的边必定是新图中最大的边!也就是说,每次加入一条边,求出当前图中经过该边的点对数就行了。。。求一个图中经过该边的点对数,将该边割开,分别从两个端点dfs,左边能遍历到x个点,右边能遍历到y个点,那么点对数就是x*y了。
原图不连通的情况也是存在的吧,这个几乎对算法不影响,只需在进入MST的点数==n的时候终止函数就行了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
#include<vector>
#include<string>
#include<cstdio>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define LL long long
#define PB push_back
#define eps 1e-10
#define debug puts("**debug**")
using namespace std; const int maxn = 10010;
const int maxm = 555555;
const int INF = 1e9;
int n, m, dfs_clock, q, f, cnt, fa[maxn];
LL sum[maxn*2];
bool seen[maxn];
vector<int> edge; struct E
{
int u, v, w;
E(){}
E(int u, int v, int w) : u(u), v(v), w(w){}
bool operator < (const E& rhs) const
{
return w < rhs.w;
}
}e[maxm]; //kruskal的边 vector<int> G[maxn]; //dfs用
inline void add(int a, int b)
{
G[a].PB(b);
G[b].PB(a);
} int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); } void dfs(int u, int fa)
{
dfs_clock++;
REP(i, G[u].size())
{
int v = G[u][i];
if(v != fa) dfs(v, u);
}
} void MST()
{
int ret = 0;
cnt = 1;
sum[0] = 0;
CLR(seen, 0);
sort(e, e+m); REP(i, m)
{
int x = findset(e[i].u), y = findset(e[i].v);
if(x != y)
{
//统计进入森林的点数
if(!seen[e[i].u]) ret++;
if(!seen[e[i].v]) ret++;
seen[e[i].u] = 1;
seen[e[i].v] = 1; fa[x] = y;
add(e[i].u, e[i].v); //将边切割双向统计两边点数
dfs_clock = 0;
dfs(e[i].u, e[i].v);
int a = dfs_clock; dfs_clock = 0;
dfs(e[i].v, e[i].u);
int b = dfs_clock; //edge保存所有MST中边 sum[i]为前i条边和
edge.PB(e[i].w);
sum[cnt] = sum[cnt-1] + a*b;
cnt++;
}
if(ret == n) return ; //终止MST
}
return ;
} void solve()
{
scanf("%d", &q);
while(q--)
{
scanf("%d", &f);
int t = lower_bound(edge.begin(), edge.end(), f) - edge.begin();
//找到f的lower_bound 答案便是总和减去小于f的点对和 注意乘以2
printf("%lld\n", (sum[cnt-1]-sum[t])*2);
}
} int main()
{
while(~scanf("%d%d", &n, &m))
{
REP(i, n) G[i].clear(), fa[i] = i;
edge.clear();
REP(i, m)
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); MST(); solve(); }
return 0;
}
hdu 4750 Count The Pairs (2013南京网络赛)的更多相关文章
- HDU 4751 Divide Groups (2013南京网络赛1004题,判断二分图)
Divide Groups Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 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 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- HDU 4759 Poker Shuffle(2013长春网络赛1001题)
Poker Shuffle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4763 Theme Section (2013长春网络赛1005,KMP)
Theme Section Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4745 Two Rabbits (2013杭州网络赛1008,最长回文子串)
Two Rabbits Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...
- HDU 4734 F(x) (2013成都网络赛,数位DP)
F(x) Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU 4731 Minimum palindrome (2013成都网络赛,找规律构造)
Minimum palindrome Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 2013南京网赛1003 hdu 4750 Count The Pairs
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意:给出一个无向图,f(a,b)表示从点a到点b的所有路径中的每条路径的最长边中的最小值,给出 ...
随机推荐
- C#使用自定义字体(从文件获取)
在进行软件开发,尤其是开发WinForm程序时,有时为了实现界面的美化,不可避免的需要使用一些特殊的字体,但是在开发完成之后,将程序移到其他的机器上时,由于这些机器可能没有安装相应的字体,所以整个界面 ...
- OpenVPN莫名其妙断线的问题及其解决
1.问题 不得不说,这是一个OpenVPN的问题,该问题几乎每个使用OpenVPN的人都碰到过,也有很多人在网上发问,然而一直都没有人能给出解决办法,甚至很多帖子上表示因为这个问题而放弃了使用Open ...
- [Java 并发] Java并发编程实践 思维导图 - 第一章 简单介绍
阅读<Java并发编程实践>一书后整理的思维导图.
- ToString()和Convert.ToString()的区别
ToString()和Convert.ToString()的区别 一般情况下,这两种方法都可以通用,但是当返回的数据类型中有可能出现null值时如果调用ToString方法了,就会返回NullRefe ...
- struts2面试题
由于找了很久的工作都没有找的,只能四处收集那个面试题的.和看面试题的 还有那个记忆力也不是很好了的,而那些公司面试的时候总会有一个面试题的! 在这里分享给大家(那个本来是想上传文件的,但是找不到的 ...
- 不同浏览器对URL最大长度的限制(转)
1.今天碰到一个bug,window.open后面的页面,接收参数不全,导致后台报错.实验了一下.发现是使用get方法请求服务器时,URL过长所致 微软官方的说明: http://support.mi ...
- (原)caffe在ubuntu中设置GPU的ID号及使用多个GPU
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5884892.html 参考网址: http://caffe.berkeleyvision.org/tu ...
- (原)mkl用到的函数
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5585301.html 计算 $C=\alpha *A*B+\beta *C$: void cblas_ ...
- Yii CDbCriteria的常用方法
$criteria = new CDbCriteria; $criteria->addCondition("id=1"); //查询条件,即where id = 1 $cri ...
- 用php逐行读取文件
做个备份年纪大了,都不愿意自己思考了 $str = file_get_contents($tmpfilename);//获得内容 $arr = explode("\n",$str) ...