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