SCU2016-02 B题 (缩点+LCA)
来源:互联网 发布:手机淘宝不能买彩票吗 编辑:程序博客网 时间:2024/06/15 23:22
分析:
把强联通分支全部缩成点,变成一颗树,然后跑一下LCA,每一次加边都会在树上形成一个环,环上所有的边都将不再是桥,并且把环缩成点。
#include <cstdio>#include <cstring>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define pr(x) cout << #x << ": " << x << " " #define pl(x) cout << #x << ": " << x << endl;#define N 100005#define M 200005using namespace std ;struct node{ int e , next ;}p[2*M+1000] ;int head[N] , dfn[N] , low[N] , vist[N] , pre[N] ;bool mark[N] ;int n , m , num , cnt , id , q ;void add( int x , int y ){ p[num].e = y ; p[num].next = head[x] ; head[x] = num++ ; p[num].e = x ; p[num].next = head[y] ; head[y] = num++ ;}void dfs( int x ){ vist[x] = 1 ; dfn[x] = low[x] = ++id ; for ( int i = head[x] ; i != -1 ; i = p[i].next ) { int v = p[i].e ; if( !vist[v] ) { pre[v] = x ; dfs( v ) ; low[x] = min( low[x] , low[v] ) ; if ( low[v] > dfn[x] )//map[x][v]就是桥 { cnt++ ; mark[v] = true ; } } else if ( vist[v] && v != pre[x] ) low[x] = min( low[x] , dfn[v] ) ; } //vist[x] = 2 ;}void find( int x , int y ){ while( dfn[x] > dfn[y] ) { if ( mark[x] ) { cnt-- ; mark[x] = false ; } x = pre[x] ; } while ( dfn[y] > dfn[x] ) { if ( mark[y] ) { cnt-- ; mark[y] = false ; } y = pre[y] ; } while ( x!= y ) { if ( mark[x] ) { cnt-- ; mark[x] = false ; } if ( mark[y] ) { cnt-- ; mark[y] = false ; } x = pre[x] ; y = pre[y] ; }}int main(){ int i , x , y ; int cas = 1 ; while ( scanf ( "%d%d" , &n , &m ) , n + m ) { memset( head , -1 , sizeof( head )) ; num = 0 ; for ( i = 1 ; i <= m ; i++ ) { scanf ( "%d%d" , &x , &y ) ; add( x , y ) ; } memset( dfn , 0 , sizeof ( dfn )) ; memset( low , 0 , sizeof ( low )) ; memset( vist , 0 , sizeof ( vist )) ; memset( mark , false , sizeof ( mark )) ; //求强连通,缩点 cnt = id = 0 ; for ( i = 1 ; i <= n ; i++ ) if ( !dfn[i] ) dfs( i ); scanf ( "%d" , &q ); printf ( "Case %d:\n" , cas++ ) ; while ( q-- ) { scanf ( "%d%d" , &x , &y ) ; //两点是否在同一分支中 if ( low[x] == low[y] ) { printf ( "%d\n" , cnt ) ; continue ; } //求公共最近祖先 find ( x , y ); printf ( "%d\n" , cnt ) ; } printf ( "\n" ) ; } return 0 ;}
0 0
- SCU2016-02 B题 (缩点+LCA)
- SCU2016-02 A题(LCA)
- SCU2016-02 G题 (技巧)
- SCU2016-02 M题 (dp)
- SCU2016-02 P题 (凸包)
- SCU2016-02 I题 (反转技巧)
- SCU2016-02 J题 (开关反转)
- SCU2016-02 T题 (LIS)
- SCU2016-04 B题 枚举+ bfs最短路
- hdu 4674 (缩点 + 倍增LCA)
- Network(Tarjan+缩点+LCA)
- SCU2016-02 Q题区间dp入门
- SCU2016-02 O题 概率dp
- SCU2016-02 Q题区间dp
- SCU2016-02 R题概率dp
- SCU2016-02 S题 区间二分
- SCU2016-04 F题 (大模拟)
- SCU2016-05 K题 (模拟水)
- L1-003. 个位数统计-PAT团体程序设计天梯赛GPLT
- 【Android】jni.h源文件/访问数组(JNI)
- js给table tr加双击事件,并自己加新参数
- C#打印条码的几种方式
- ionic build ios(windows8虚拟机 使用ionic 打包ios,整个过程就是ionic build ios)
- SCU2016-02 B题 (缩点+LCA)
- LeetCode 188 - Best Time to Buy and Sell Stock IV
- Fresco图片加载框架使用
- 测试
- thymeleaf学习文档
- Struts2_01_Action简介_HelloWorld
- React 组件的API(组件实例)介绍
- L1-007. 念数字-PAT团体程序设计天梯赛GPLT
- Merge into的注意点之ORA-30926: 无法在源表中获得一组稳定的行?