HDU 2874 Connections between cities

这个题搞的我好纠结呀!一直是WA,后来才知道自己记录的时候搞错了,ans应该为-1而不是0,因为当时同一个点时,距离为0;

这里要用到LCA,我们的距离为两个子节点到根的距离和减去最近祖先的距离的2倍;

#include<cstdio>
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
class node
{
public:
int en;
int len;
};

vector<node>tree[10024],Qes[10024];
int dist[10024],set[10024],visit[10024],ans[1000024];
void init( int n )
{
for(int i=0;i<=n;i++)
{
dist[i]=0;
set[i]=i;
visit[i]=0;
// indegree[i]=0;
tree[i].clear( );
Qes[i].clear( );
}
}
inline int find( int x )
{
return set[x]==x?x:set[x]=find( set[x] );
}

inline void LCA( int num,int d,int root )
{
dist[num]=d;
set[num]=num;
visit[num]=root;//标记为那棵树的根
int size=tree[num].size();
for( int i=0; i<size; i++ )
{
if( !visit[tree[num][i].en] )
{
LCA( tree[num][i].en,tree[num][i].len+d ,root);
set[tree[num][i].en]=num;
}
}
size=Qes[num].size( );
for( int i=0;i<size; i++ )
{
if( visit[Qes[num][i].en] )
{
if( visit[Qes[num][i].en]==root )//如果被标记过并且是同一棵树,就找最近祖先
{
ans[Qes[num][i].len]=dist[num]+dist[Qes[num][i].en]-2*dist[find( Qes[num][i].en )];
}
else ans[Qes[num][i].len]=-1;//要注意为-1,不能为0同点为0
}
}
}
int main( )
{
int n,m,Case,x,y,dis,N;
while( scanf( "%d %d %d",&N,&n,&m )==3 )
{
init( N );
for( int i=1; i<= n ;i++ )
{
scanf( "%d %d %d",&x,&y,&dis );
node T;
T.en = y;
T.len = dis;
tree[x].push_back( T );
// indegree[y]++;
T.en=x;
tree[y].push_back( T );
}
for( int i=1;i <= m ;i++ )
{
scanf( "%d %d",&x,&y );
node T;
T.en=y;
T.len=i;
// ans[i]=-1;
Qes[x].push_back( T );
T.en=x;
Qes[y].push_back( T );
}
for( int i=1;i<=N; i++ )
{
if( visit[i]==0 )//多棵树的情况,因为同一棵树任何一个节点都可以做根节点
{
LCA( i,0,i );
}
}
for( int i=1;i<=m ; i++ )
{
if( ans[i]==-1 )
{
printf( "Not connected\n" );
}
else printf( "%d\n",ans[i] );
}
}
return 0;
}

 

你可能感兴趣的:(Connection)