HDU Intelligence System(tarjan+缩点)
2012-11-03 11:28
99 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3072
最近为了CF上的一道题,又把强连通分支的tarjan算法看了一遍,为了加深印象,就做了HDU上的这题。。。。
题意:有一个情报系统,要从0开始传播一个情报,如果两个人可以互达那么两人之间的传播费用为0 ,否则两人之间的传播费用为ci,求要情报传达到每个人的最小费用。
思路:既然一个强连通分支内的传播费用为0,求图中有几个强连通分支,缩点后求各点之间的最小费用。
代码:
View Code
最近为了CF上的一道题,又把强连通分支的tarjan算法看了一遍,为了加深印象,就做了HDU上的这题。。。。
题意:有一个情报系统,要从0开始传播一个情报,如果两个人可以互达那么两人之间的传播费用为0 ,否则两人之间的传播费用为ci,求要情报传达到每个人的最小费用。
思路:既然一个强连通分支内的传播费用为0,求图中有几个强连通分支,缩点后求各点之间的最小费用。
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #define N 100005 #define M 50005 using namespace std ; const int INF = ( 1 << 30 ); struct node { int e , len ; int next ; }p ; int head[M] , n , m , num , cnt , id ; bool used[M] , vist[M] ;//used[i]表示点i是否遍历过,vist[i]表示点i是否在栈里; int dis[M] , dfn[M] , low[M] , belong[M] ; stack<int>q ; //初始化 void init() { num = cnt = id = 0 ; for ( int i = 0 ; i <= n ; i++ ) { dfn[i] = low[i] = 0 ; used[i] = vist[i] = false ; dis[i] = INF ; head[i] = -1 ; } while ( !q.empty()) q.top(); } void add ( int x , int y , int z ) { p[num].e = y ; p[num].len = z ; p[num].next = head[x]; head[x] = num++ ; } void tarjan( int x ) { int i , v ; dfn[x] = low[x] = ++id ; used[x] = vist[x] = true ; q.push( x ) ; for ( i = head[x] ; i != -1 ; i = p[i].next ) { v = p[i].e ; if( !used[v] ) { tarjan( v ) ; low[x] = min( low[x] , low[v] ); } else if( vist[v] ) { low[x] = min( low[x] , dfn[v] ); } } if ( dfn[x] == low[x] ) { cnt++ ; do { v = q.top(); q.pop(); belong[v] = cnt ; vist[v] = false ; }while( v != x ) ; } } int main() { int i , j , x , y , z ; while ( scanf ( "%d%d" , &n , &m ) != EOF ) { init(); for ( i = 1 ; i <= m ; i++ ) { scanf ( "%d%d%d" , &x , &y , &z ); //x++ ; y++ ; add ( ++x , ++y , z ) ; } for ( i = 1 ; i <= n ; i++ ) if ( !dfn[i] ) tarjan( i ) ; for ( i = 1 ; i <= n ; i++ ) { for ( j = head[i] ; j != -1 ; j = p[j].next ) { z = p[j].e ; x = belong[i]; y = belong[z] ; if ( x != y ) dis[y] = min( dis[y] , p[j].len ) ; } } int sum = 0 ; for ( i = 1 ; i <= n ; i++ ) if ( dis[i] < INF ) sum += dis[i] ; printf ( "%d\n" , sum ) ; } return 0 ; }
相关文章推荐
- HDU 3836 Equivalent Sets(tarjan + 压缩强连通)
- hdu 2586 tarjan 板子
- HDU 2586 How far away? LCA 离线tarjan
- HDU - 1269 - 迷宫城堡 (tarjan求强连通分量)
- hdu1269 Tarjan强连通分量 模板
- LCA tarjan 算法 练习: hdu 2586 + poj 1986
- hdu--2586--lca_tarjan<证明tarjan这个人很流弊>
- HDU 1269 移动城堡 联通分量 Tarjan
- 迷宫城堡 HDU - 1269(tarjan求强联通)
- hdu1269-图论-Tarjan-迷宫城堡
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- How far away ? HDU - 2586 tarjan求LCA
- hdu 4612 Warm up (带有重边的无向图Tarjan+树的直径)
- hdu 2586 tarjan 板子
- HDU_2586 && HDU_2874 (LCA+tarjan)
- [HDU 4587] TWO NODES (Tarjan+割点)
- HDU 2586 (Tarjan)
- hdu 3072 Intelligence System(Tarjan 求连通块间最小值)
- HDU 3072 Intelligence System(tarjan+DAG上的最小生成树形图)
- 迷宫城堡 - HDU 1269 Tarjan 模板题