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

6 6 8
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
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 题解的更多相关文章

  1. Kruskal重构树+LCA || BZOJ 3732: Network

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3732 题解:Kruskal重构树板子 代码: #include<cstdio> ...

  2. BZOJ 3732 Network

    2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...

  3. BZOJ 3732: Network 最小生成树 倍增

    3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...

  4. BZOJ 3732 Network —— 最小生成树 + 倍增LCA

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...

  5. bzoj 3732 Network(最短路+倍增 | LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3732 [题意] 给定一个无向图,处理若干询问:uv路径上最长的边最小是多少? [思路一 ...

  6. bzoj 2669 题解(状压dp+搜索+容斥原理)

    这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...

  7. BZOJ 3732 Network Link-Cut-Tree (我是认真的!!

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...

  8. bzoj一句话题解

    发现好多人都在搞这个...本人也想来试试(Solved刚到70就搞这个靠不靠谱啊喂).会更新的.嗯. 1000-1029 1000 A+B problem (这个还需要一句话吗?). 1001 狼抓兔 ...

  9. BZOJ 一句话题解

    菜鸡刷题记录 [题号:题解] 1008:简单排列组合 #include <bits/stdc++.h> using namespace std; #define ll long long ...

随机推荐

  1. 解析PHP处理换行符的问题 \r\n

    一首先说说 \r 与\n的区别回车”(Carriage Return)和“换行”(Line Feed)这两个概念的来历和区别.在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model ...

  2. 无废话ExtJs 入门教程十[单选组:RadioGroup、复选组:CheckBoxGroup]

    无废话ExtJs 入门教程十[单选组:RadioGroup.复选组:CheckBoxGroup] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个一个单选组,一个复 ...

  3. hdu 2203:亲和串(水题,串的练习)

    亲和串 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  4. wp8 入门到精通 聊天控件

    <Grid > <Grid x:Name="bubble_right" VerticalAlignment="Center" RenderTr ...

  5. Java学习随笔2:Java复合赋值表达式的小问题

    问题:i += j只是i = i + j的简写么? 答案:非也!看下面的程序: int i = 5; long j = 8; i += j; // 可以通过编译且结果正确 i = i + j; // ...

  6. 使用 json_in_java

    // */ // ]]> java_in_json Table of Contents 1. Java 使用 Json 1.1. 下载地址: 1.2. 构造 json 字符串 1.3. 解析 j ...

  7. MPAndroidChart饼图属性及相关设置

    公司最近在做统计功能,所以用到了饼图,在网上查了一些资料最终决定使用MPAndroidChart,使用起来非常方便,还有一些问题通过各种查找,终于解决...废话不多说,先看下效果图: 布局文件: &l ...

  8. MySQL数据库监控

    MySQL MTOP由PHP和Python开发,所以监控机需要安装PHP运行环境和Python环境.需要的核心包如下: 1.MySQL 5.0及以上(用来存储监控系统采集的数据) 2.Apache 2 ...

  9. Portlet简述

    一.Portlet是什么? Portlet是基于java的web组件,由portlet容器管理,并由容器处理请求,生产动态内容.Portals使用portlets作为可插拔用户接口组件,提供信息系统的 ...

  10. 在C#程序中实现插件架构

    阅读提示:这篇文章将讲述如何利用C#奇妙的特性,实现插件架构,用插件(plug-ins)机制建立可扩展的解决方案. 在.NET框架下的C#语言,和其他.NET语言一样提供了很多强大的特性和机制.其中一 ...