zoukankan      html  css  js  c++  java
  • HDU4612+Tarjan缩点+BFS求树的直径

    tarjan+缩点+树的直径
    题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少。
    先tarjan缩点,再在这棵树上求直径。加的边即是连接这条直径的两端。

      1 /*
      2 tarjan+缩点+树的直径
      3 题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少。
      4 先tarjan缩点,再在这棵树上求直径。加的边即是连接这条直径的两端。
      5 */
      6 #pragma comment(linker, "/STACK:1024000000,1024000000")  
      7 #include<stdio.h>
      8 #include<string.h>
      9 #include<stdlib.h>
     10 #include<stack>
     11 #include<algorithm>
     12 #include<iostream>
     13 #include<queue>
     14 #include<map>
     15 #include<math.h>
     16 using namespace std;
     17 typedef long long ll;
     18 //typedef __int64 int64;
     19 const int maxn = 300015;
     20 const int maxm = 2000015;
     21 const int inf = 0x7fffffff;
     22 const double pi=acos(-1.0);
     23 const double eps = 1e-8;
     24 struct Edge{
     25     int v,next;
     26 }edge[ maxm<<1 ],edgeTree[ maxm<<1 ];
     27 int cnt,cnt2,head[ maxn ],head2[ maxn ];
     28 int vis[ maxn ];
     29 int dfn[ maxn ];
     30 int low[ maxn ];
     31 int be[ maxn ];//缩点
     32 int sum;//the num of "缩点"
     33 int id;
     34 stack<int>sta;
     35 queue<int>q;
     36 int maxNode,maxs;//这棵树的直径maxs
     37 int dis[ maxn ];
     38 map<int,int>mp;
     39 void init(){
     40     cnt = cnt2 = 0;
     41     id = 0;
     42     sum = 0;
     43     //mp.clear();
     44     memset( head,-1,sizeof( head ) );
     45     memset( head2,-1,sizeof( head2 ) );
     46     memset( dfn,-1,sizeof( dfn ) );
     47     memset( vis,-1,sizeof( vis ) );
     48     memset( low,-1,sizeof( low ) );
     49     while( !sta.empty() )
     50         sta.pop();
     51 }
     52 void addedge( int a,int b ){
     53     edge[ cnt ].v = b;
     54     edge[ cnt ].next = head[ a ];
     55     head[ a ] = cnt++;
     56 }
     57 void addedge2( int a,int b ){
     58     edgeTree[ cnt2 ].v = b;
     59     edgeTree[ cnt2 ].next = head2[ a ];
     60     head2[ a ] = cnt2++;
     61 }
     62 
     63 void tarjan( int u,int Link ){
     64     dfn[ u ] = low[ u ] = id++;
     65     vis[ u ] = 1;
     66     sta.push( u );
     67     int cc = 0;
     68     for( int i=head[u];i!=-1;i=edge[i].next ){
     69         int v = edge[ i ].v;
     70         if( dfn[ v ]==-1 ){
     71             tarjan( v,u );
     72             low[ u ] = min( low[ u ],low[ v ] );
     73         }
     74         else if( Link==v ){
     75             if( cc ) low[ u ] = min( low[ u ],dfn[ v ] );
     76             cc++;
     77         } 
     78         else if( vis[ v ]==1 ){
     79             low[ u ] = min( low[ u ],dfn[ v ] );
     80         }
     81     }
     82     if( dfn[u]==low[u] ){
     83         sum++;
     84         int tt;
     85         while( 1 ){
     86             tt = sta.top();
     87             sta.pop();
     88             vis[ tt ] = 0;
     89             be[ tt ] = sum;
     90             if( tt==u ) break;
     91         }
     92     }
     93 }
     94 void buildTree( int n ){
     95     for( int i=1;i<=n;i++ ){
     96         for( int j=head[ i ];j!=-1;j=edge[ j ].next ){
     97             if( be[i]!=be[edge[j].v] ){
     98                 addedge2( be[i],be[edge[j].v] );
     99             }
    100         }
    101     }
    102 }
    103 void bfs( int s,int n ){
    104     memset( vis,0,sizeof( vis ) );
    105     vis[ s ] = 1;
    106     while( !q.empty() )
    107         q.pop();
    108     q.push( s );
    109     dis[ s ] = 0;
    110     maxs = 0;
    111     while( !q.empty() ){
    112         int cur = q.front();
    113         q.pop();
    114         if( dis[ cur ]>=maxs ){
    115             maxs = dis[ cur ];
    116             maxNode = cur;
    117         }
    118         for( int i=head2[ cur ];i!=-1;i=edgeTree[ i ].next ){
    119             int v = edgeTree[ i ].v;
    120             if( vis[ v ]==1 ) continue;
    121             vis[ v ] = 1;
    122             dis[ v ] = dis[ cur ]+1;
    123             q.push( v );
    124         }    
    125     }
    126     return ;
    127 }
    128 int dfs(int u,int p)  
    129 {  
    130     int max1=0,max2=0;  
    131     for (int i=head2[u];i!=-1;i=edgeTree[i].next)  
    132     {  
    133         int v=edgeTree[i].v;  
    134         if (v==p) continue;  
    135         int tmp=dfs(v,u)+1;  
    136         if (max1<tmp) max2=max1,max1=tmp;  
    137         else if (max2<tmp) max2=tmp;  
    138     }  
    139     maxs=max(maxs,max1+max2);  
    140     return max1;  
    141 } //dfs求树的直径 ok
    142 int main(){
    143     int n,m;
    144     while( scanf("%d%d",&n,&m)&&(n+m) ){
    145         int a,b;
    146         init();
    147         while( m-- ){
    148             scanf("%d%d",&a,&b);
    149             if( a==b ) continue;
    150             //if( mp[min(a,b)] == max(a,b) ) continue;
    151             //mp[min(a,b)] = max(a,b);
    152             //不能这样去重边???
    153             addedge( a,b );
    154             addedge( b,a );
    155         }
    156         for( int i=1;i<=n;i++ ){
    157             if( dfn[i]==-1 ){
    158                 tarjan( i,-1 );
    159             }
    160         }
    161         buildTree( n );
    162         bfs( 1,sum );
    163         bfs( maxNode,sum );
    164         //printf("sum=%d, maxs=%d
    ",sum,maxs);
    165         //maxs = 0;
    166         //dfs( 1,-1 );
    167         printf("%d
    ",sum-1-maxs);
    168     }
    169     return 0;
    170 }
    View Code
    keep moving...
  • 相关阅读:
    SpringMVC处理请求
    SpringMVC的启动
    数据结构
    Collections工具类
    位运算
    web应用
    spring Environment
    servlet及jsp之间的请求转发
    spring AOP
    Spring 事件
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3251907.html
Copyright © 2011-2022 走看看