BZOJ 3732 题解
3732: Network
Description
给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。
图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).
现在有 K个询问 (1 < = K < = 15,000)。
每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?
Input
第一行: N, M, K。
第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。
第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?
Output
对每个询问,输出最长的边最小值是多少。
Sample Input
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1
Sample Output
5
5
4
4
7
4
5
HINT
1 <= N <= 15,000
1 <= M <= 30,000
1 <= d_j <= 1,000,000,000
1 <= K <= 15,000
—————————————分割线—————————————
为了保证最长边最小,即求图的最小瓶颈生成树,原图的最小瓶颈生成树就是最小生成树。
代码:
/**************************************************************
Problem: 3732
User: shadowland
Language: C++
Result: Accepted
Time:372 ms
Memory:32768 kb
****************************************************************/ /*
树链剖分
author : SHHHS
2016-10-02 09:04:15
*/
#include "bits/stdc++.h" using namespace std ; struct MST{int x , y , val ; } ;
struct Edge{int to , next , val ; } ;
struct SegTree{int l , r , mintr ; } ;
const int INF = ;
const int maxN = ;
typedef long long QAQ ; MST MST_e[ maxN ] ;
Edge e [ maxN ] ;
SegTree tr[ maxN << ] ;
int head[maxN] , father[maxN], DFN[maxN], hv[maxN],rank[maxN], E_val[maxN], start[maxN], pre[maxN];
bool vis[maxN] ; int cnt , dfs_num ;
QAQ Ans = INF ; void Init ( int n ){for ( int i = ; i <= n ; ++i )father[ i ] = i ; }
int getfa ( int x ){if(father[x] == x)return x ; else return father[ x ] = getfa( father[ x ] ) ; }
inline bool cmp ( MST x , MST y ){ return x.val < y.val ; }
inline int gmin ( int x , int y ){ return x < y ? y : x ; }
inline void Union_Set ( const int x , const int y ){ father[ x ] = y ; }
inline void Push_up ( int i ){tr[ i ].mintr = gmin (tr[ i << | ].mintr, tr[ i << ].mintr) ; }
inline void gswap ( int &x , int &y ) {int temp = x ; x = y ; y = temp ; }
bool Check ( const int x , const int y ) { return getfa( x ) == getfa( y ) ? true : false ; } void Build_Tree ( int x , int y , int i ) {
tr[ i ].l = x ;
tr[ i ].r = y ;
if ( x == y ) tr[ i ].mintr = E_val[ rank[ x ] ] ;
else {
int mid = ( tr[ i ].l + tr[ i ].r ) >> ;
Build_Tree ( x , mid , i << ) ;
Build_Tree ( mid + , y , i << | ) ;
Push_up ( i ) ;
}
} inline void Add_Edge ( const int x , const int y , const int _val ) {
e[ ++cnt ].to = y ;
e[ cnt ].val = _val ;
e[ cnt ].next = head[ x ] ;
head[ x ] = cnt ;
} void MST ( int N , int M ) {
int cnt_ = ;
Init ( N ) ;
sort ( MST_e + , MST_e + M + , cmp ) ;
for ( int i = ; i <= M ; ++i ) {
int px = getfa ( MST_e[i].x ) ;
int py = getfa ( MST_e[i].y ) ;
if ( px == py ) continue ;
else {
Union_Set ( px , py ) ;
Add_Edge ( MST_e[i].x , MST_e[i].y , MST_e[i].val ) ;
Add_Edge ( MST_e[i].y , MST_e[i].x , MST_e[i].val ) ;
++cnt_ ;
}
if ( cnt_ == N - ) break ;
}
} int Init_DFS ( const int x , const int fa ) {
vis[ x ] = true ;
int cnt_ = , max_ = ;
for ( int i = head[ x ] ; i ; i = e[ i ].next ) {
int temp = e[ i ].to ;
if ( temp == fa ) continue ;
int _ = Init_DFS ( temp , x ) ;
if ( _ > max_ ) {
max_ = _ ;
hv[ x ] = temp ;
}
cnt_ += _;
}
return cnt_ ;
} void DFS ( const int x , const int fa ) {
vis [ x ] = false ;
if ( !start[ x ] ) start[ x ] = start[ fa ] ;
DFN[ x ] = ++ dfs_num ;
rank[ dfs_num ] = x ;
if ( hv[ x ] ) DFS ( hv[ x ] , x ) ;
for ( int i = head[ x ] ; i ; i = e[ i ].next ) {
if ( e[ i ].to == fa ) continue ;
E_val[ e[ i ].to ] = e[ i ] .val ;
if ( e[ i ].to != hv[ x ] && e[ i ].to != fa && vis[ e[ i ].to ] == true ) {
int temp = e[ i ].to ;
start[ temp ] = temp ;
pre [ temp ] = x ;
DFS ( temp , x ) ;
}
}
} QAQ Query_Tree ( int q , int w , int i ) {
if ( q <= tr[i].l && w >= tr[i].r ) return tr[i].mintr;
else {
int mid = ( tr[ i ].l + tr[ i ].r ) >> ;
if ( q > mid ) return Query_Tree ( q , w , i << | ) ;
else if ( w <= mid ) return Query_Tree ( q , w , i << ) ;
else return gmin ( Query_Tree ( q , w , i << | ) , Query_Tree ( q , w , i << ) ) ;
}
} void Solve ( const int x , const int y ) {
int px = x , py = y ;
while ( start[ px ] != start[ py ] ) {
if ( DFN[ start[ px ] ] > DFN[ start[ py ] ] ) {
Ans = gmin ( Ans , Query_Tree ( DFN[start[ px ]] , DFN[px] , ) ) ;
px = pre[ start[ px ] ] ;
}
else {//py跳
Ans = gmin ( Ans , Query_Tree ( DFN[start[ py ]] , DFN[py] , ) ) ;
py = pre[ start[ py ] ] ;
}
} if ( px == py ) return ;
int dfn_px = DFN[ px ] , dfn_py = DFN[ py ] ;
if ( dfn_px > dfn_py ) gswap ( dfn_px , dfn_py ) ;
Ans = gmin ( Ans , Query_Tree ( dfn_px + , dfn_py , ) );
} void DEBUG__ ( int n ){
putchar ( '\n' ) ;
for ( int i = ; i <= n ; ++i )printf ("%d : %d %d\n", i , E_val[rank[ i ] ] , E_val[ i ]) ;
putchar ( '\n' ) ;
}
void DEBUG_ ( int m ) {
putchar('\n');
for ( int i = ; i <= m ; ++i ) printf ("%d %d %d\n" , MST_e[ i ].x , MST_e[ i ].y , MST_e[ i ].val) ;
}
int main ( ) {
int N , M , Q , _x , _y ;
scanf ( "%d%d%d" , &N , &M , &Q ) ;
for ( int i = ; i <= M ; ++i )
scanf ( "%d%d%d" , &MST_e[ i ].x , &MST_e[ i ].y , &MST_e[ i ].val ) ;
MST ( N , M ) ; Init_DFS ( , ) ;
start[ ] = ;
E_val[ ] = -INF ; //DEBUG_( M );
DFS ( , ) ; Build_Tree ( , dfs_num , ) ; //DEBUG__( dfs_num ) ;
while ( Q-- ){
Ans = -INF ;
scanf ( "%d%d" , &_x , &_y ) ;
if ( Check ( _x , _y ) ) {
Solve ( _x , _y ) ;
printf ( "%lld\n" , Ans ) ;
}
}
return ;
}
BZOJ 3727
NOIP_RP++;
2016-10-11 03:53:37
(完)
BZOJ 3732 题解的更多相关文章
- Kruskal重构树+LCA || BZOJ 3732: Network
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3732 题解:Kruskal重构树板子 代码: #include<cstdio> ...
- BZOJ 3732 Network
2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...
- BZOJ 3732: Network 最小生成树 倍增
3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...
- bzoj 3732 Network(最短路+倍增 | LCT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3732 [题意] 给定一个无向图,处理若干询问:uv路径上最长的边最小是多少? [思路一 ...
- bzoj 2669 题解(状压dp+搜索+容斥原理)
这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...
- BZOJ 3732 Network Link-Cut-Tree (我是认真的!!
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...
- bzoj一句话题解
发现好多人都在搞这个...本人也想来试试(Solved刚到70就搞这个靠不靠谱啊喂).会更新的.嗯. 1000-1029 1000 A+B problem (这个还需要一句话吗?). 1001 狼抓兔 ...
- BZOJ 一句话题解
菜鸡刷题记录 [题号:题解] 1008:简单排列组合 #include <bits/stdc++.h> using namespace std; #define ll long long ...
随机推荐
- eclipse 创建项目时出现appcompat_v7?
建项目时不出现appcompat_v7包的方法.既然appcompat_v7包是一个能让2.1以上全使用上4.0版本的界面的支持库,那么如图所示,我们建项目时直接把最小SDK选在Android4.0以 ...
- Tiny Rss Reader - 迷你RSS阅读器
发布新软件 TinyRss: Windows平台上的一个小巧的Rss阅读器. 用户界面: 项目地址: https://github.com/movsb/tinyrss.git 测试下载: http:/ ...
- php重修
阅读顺序: http://www.laruence.com/2008/08/11/147.html 深入浅出php http://www.laruence.com/2008/06/18/221.ht ...
- 简单的redis 性能测试
C:\Users\luhan.qian\Desktop\Tools\redis C:\Users\luhan.qian\Desktop\Tools\redis $ redis-benchmark.ex ...
- PHP模拟POST请求,获取response内容
/* * 模拟POST请求,获取response内容 */ protected function curl($url, $type, $header, $data) { $CURL_OPTS = ar ...
- 在Salesforce中通过 Debug Log 方式 跟踪逻辑流程
在Salesforce中通过 Debug Log方式 跟踪逻辑流程 具体位置如下所示: Setup ---> Logs ---> Debug Logs ---> Monitored ...
- HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP
考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...
- python学习第二天
dict字典 把数据放入dict:直接赋值.初始化时指定 pop删除key set集合 add添加元素 remove删除元素 字符串str是不可变对象,对字符串的操作都会返回新的字符串 pass 什么 ...
- 遍历PspCidTable表检测隐藏进程
一.PspCidTable概述 PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的,但它与每个进程私有的句柄表有以下不同: 1.PspCidTable中存放的对象是系统中所有的进程 ...
- JSON语法简介 介绍 json
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation),类似 XML,但比 XML 更小.更快,更易解析. 实例 { "employees ...