HDU2874+LCA+tarjan
可用tarjan来做。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 lca+tarjan 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<algorithm> 8 #include<iostream> 9 #include<queue> 10 #include<map> 11 #include<math.h> 12 using namespace std; 13 typedef long long ll; 14 //typedef __int64 int64; 15 const int maxn = 10005; 16 const int maxm = 1000005; 17 18 int cnt,head[ maxn ],ex_cnt,ex_head[ maxn ]; 19 struct node{ 20 int u,next,val; 21 }edge[ maxn<<4 ],ex_edge[ maxm<<1 ]; 22 void init(){ 23 cnt = ex_cnt = 0; 24 memset( head,-1,sizeof( head ) ); 25 memset( ex_head,-1,sizeof( ex_head ) ); 26 } 27 void addedge( int a,int b,int c ){ 28 edge[ cnt ].u = b; 29 edge[ cnt ].val = c; 30 edge[ cnt ].next = head[ a ]; 31 head[ a ] = cnt++; 32 } 33 void ex_addedge( int a,int b,int c ){ 34 ex_edge[ ex_cnt ].u = b; 35 ex_edge[ ex_cnt ].val = c; 36 ex_edge[ ex_cnt ].next = ex_head[ a ]; 37 ex_head[ a ] = ex_cnt++; 38 } 39 40 int belong[ maxn ];//记录两个点是否属于同一棵树 41 int vis[ maxn ],dis[ maxn ],fa[ maxn ]; 42 43 void make_set( int x ){ 44 fa[ x ] = x; 45 } 46 int find( int x ){ 47 if( x==fa[x] ) return x; 48 return fa[x] = find( fa[x] ); 49 } 50 51 struct node2{ 52 int u,v; 53 }query[ maxm ]; 54 int ans[ maxm ];//存储答案 55 56 void dfs( int cur,int flag ){ 57 //if( vis[ cur ]==1 ) return ; 58 vis[ cur ] = 1; 59 belong[ cur ] = flag; 60 for( int i=head[ cur ];i!=-1;i=edge[ i ].next ){ 61 if( vis[ edge[ i ].u ]==0 ){ 62 dfs( edge[ i ].u,flag ); 63 } 64 } 65 return ; 66 } 67 68 void tarjan_of_lca( int cur,int dist ){ 69 make_set( cur ); 70 vis[ cur ] = 1; 71 dis[ cur ] = dist; 72 for( int i=head[ cur ];i!=-1;i=edge[ i ].next ){ 73 int v = edge[ i ].u; 74 if( vis[ v ]==0 ){ 75 tarjan_of_lca( v,dist+edge[ i ].val ); 76 fa[ v ] = cur; 77 } 78 } 79 for( int ii=ex_head[ cur ];ii!=-1;ii=ex_edge[ ii ].next ){ 80 int v = ex_edge[ ii ].u; 81 if( vis[ v ]==1 ){ 82 int val = ex_edge[ ii ].val; 83 int father = find( v ); 84 ans[ val ] = dis[ cur ]+dis[ v ]-2*dis[ father ]; 85 } 86 } 87 } 88 89 int main(){ 90 int n,m,k; 91 //freopen( "in.txt","r",stdin ); 92 while( scanf("%d%d%d",&n,&m,&k)==3 ){ 93 init(); 94 int a,b,c; 95 while( m-- ){ 96 scanf("%d%d%d",&a,&b,&c); 97 addedge( a,b,c ); 98 addedge( b,a,c ); 99 } 100 memset( vis,0,sizeof( vis ) ); 101 for( int i=1;i<=n;i++ ){ 102 belong[ i ] = i; 103 fa[ i ] = i; 104 } 105 int cc = 1;//cc表示树的标记 106 for( int i=1;i<=n;i++ ){ 107 if( vis[ i ]==0 ){ 108 dfs( i,cc ); 109 cc++; 110 } 111 } 112 for( int i=1;i<=k;i++ ){ 113 scanf("%d%d",&a,&b); 114 if( a!=b ){ 115 ex_addedge( a,b,i ); 116 ex_addedge( b,a,i ); 117 } 118 else ex_addedge( a,b,i ); 119 query[ i ].u = a; 120 query[ i ].v = b; 121 } 122 memset( vis,0,sizeof( vis ) ); 123 for( int i=1;i<=n;i++ ){ 124 if( vis[ i ]==0 ){ 125 tarjan_of_lca( i,0 ); 126 } 127 } 128 for( int i=1;i<=k;i++ ){ 129 if( belong[ query[i].u ]!=belong[ query[i].v ] ) printf("Not connected\n"); 130 else{ 131 printf("%d\n",ans[ i ]); 132 } 133 } 134 } 135 return 0; 136 }
或者很简单的dfs。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<algorithm> 8 #include<iostream> 9 #include<queue> 10 #include<vector> 11 #include<map> 12 #include<math.h> 13 typedef long long ll; 14 //typedef __int64 int64; 15 const int maxn = 10005; 16 const int maxm = 1005; 17 const int inf = 0x7FFFFFFF; 18 const double pi = acos(-1.0); 19 const double eps = 1e-8; 20 struct node{ 21 int from,to,next,val; 22 }edge[ maxn<<2 ]; 23 int cnt,head[ maxn ]; 24 int dis[ maxn ];//与公共祖先的距离 25 int fa[ maxn ];//当前点的直接父亲 26 int deep[ maxn ];//与公共祖先的距离 27 int ace[ maxn ];//公共祖先 28 29 void init(){ 30 cnt = 0; 31 memset( head,-1,sizeof( head ) ); 32 memset( fa,-1,sizeof( fa ) ); 33 } 34 35 void addedge( int a,int b,int c ){ 36 edge[ cnt ].from = a; 37 edge[ cnt ].to = b; 38 edge[ cnt ].val = c; 39 edge[ cnt ].next = head[ a ]; 40 head[ a ] = cnt++; 41 } 42 43 void dfs( int now,int now_father,int now_ace,int now_deep,int now_dis ){ 44 fa[ now ] = now_father; 45 deep[ now ] = now_deep; 46 dis[ now ] = now_dis; 47 ace[ now ] = now_ace; 48 for( int i=head[ now ];i!=-1;i=edge[ i ].next ){ 49 int v = edge[ i ].to; 50 if( fa[ v ]==-1 ) 51 dfs( v,now,now_ace,now_deep+1,now_dis+edge[ i ].val ); 52 } 53 return ; 54 } 55 int find( int x,int y ){ 56 if( x==y ) return x; 57 if( deep[ x ]>deep[ y ] ) 58 return find( fa[ x ],y ); 59 else 60 return find( x,fa[ y ] ); 61 } 62 int main(){ 63 int n,m,q; 64 while( scanf("%d%d%d",&n,&m,&q)==3 ){ 65 int a,b,c; 66 init(); 67 while( m-- ){ 68 scanf("%d%d%d",&a,&b,&c); 69 addedge( a,b,c ); 70 addedge( b,a,c ); 71 } 72 for( int i=1;i<=n;i++ ){ 73 if( fa[ i ]==-1 ){ 74 dfs( i,-1,i,0,1 ); 75 } 76 } 77 while( q-- ){ 78 scanf("%d%d",&a,&b); 79 if( ace[ a ]==ace[ b ] ){ 80 int father=find( a,b ); 81 printf("%d\n",dis[ a ]+dis[ b ]-2*dis[ father ]); 82 } 83 else printf("Not connected\n"); 84 } 85 } 86 return 0; 87 }
keep moving...