| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
我不是男人!附上小弟使用LCA的TLE算法.//Tarjan算法这是一个离线算法复杂度是O(N+Q),我在Q上无法优化,为N^2,所以超时了.路过的请帮我想想有没有办法.
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
#define MAXN 10005
#define MAXE 100005
struct edge
{
__int32 adj,dis,num;
};
vector<edge> Tree[MAXN];
__int32 set[MAXN], ancestor[MAXN], rank[MAXN], num, dis[MAXN];
bool visite[MAXN],edgeused[MAXE];
__int32 n, k,ecount;
bool input()
{
scanf("%I32d%I32d",&n,&k);
if(n+k==0) return false;//节点个数
for( __int32 i= 1; i<= n; ++i )
Tree[i].clear();
ecount=0;
memset( set, 0, sizeof(set) );
memset( dis, 0, sizeof(dis) );
memset( ancestor, 0, sizeof(ancestor) );
memset( rank, 0, sizeof(rank) );
//memset( root, 0, sizeof(root) );
num=0;
memset( visite,false, sizeof(visite) );
memset( edgeused, 0, sizeof(edgeused) );
__int32 u, v, d;
for( __int32 i= 1; i<=n-1; ++i )
{
scanf("%I32d%I32d%I32d",&u,&v,&d);
edge e1={v,d,ecount};
Tree[u].push_back(e1);
edge e2={u,d,ecount};
Tree[v].push_back(e2);
ecount++;
//root[v]++;//对每个出现的子节点进行标记,最后没有标记那个是根节点
}
return true;
}
void make_set( __int32 u )
{
set[u]= u;
}
__int32 find_set( __int32 u )
{
while( u!= set[u] ) u= set[u];
return u;
}
void union_set( __int32 u, __int32 v )
{
__int32 x= find_set(u), y= find_set(v);
if( rank[x]> rank[y] )
set[y]= x;
else
{
set[x]= y;
if( rank[x]== rank[y] ) rank[y]++;//rank表示树的深度,浅的接到深的树上.只当两棵树深度相同时的,才会让原本的树发生深度变更.
}
}
void lca( __int32 u ,__int32 high)
{
dis[u]=high;
make_set(u);
ancestor[u]= u;
for( size_t i= 0; i< Tree[u].size(); ++i )
if(!edgeused[Tree[u][i].num])
{
edgeused[Tree[u][i].num]=true;
lca( Tree[u][i].adj,high+ Tree[u][i].dis);
union_set( u, Tree[u][i].adj );//合并后,u不再是以前的u,所以要执行 ancestor[ find_set(u) ]= u;
ancestor[ find_set(u) ]= u;
}
__int32 v;
visite[u]= true;
for(v=1;v<=n;++v )//query[u][i]=v,要查询的是(u,v)的最近祖先节点
if(v!=u)
if( visite[ v ] )
{
__int32 p=ancestor[ find_set( v ) ] ;
__int32 d=dis[u]-dis[p]+dis[v]-dis[p];
// printf("u:%d v:%d p:%d d:%d\n",u,v,p,d);
if(d<=k)
num++;
}
}
int main()
{
freopen("c:/aaa.txt","r",stdin);
while( input() )
{
for( __int32 i= 1; i<= n; ++i )
// if( root[i]== 0 )
{
lca( 1,0);
break;
}
printf("%I32d\n",num );
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator