LCA(POJ1470)

//简单题,但输入好像挺恶心的,反正俺是个只会做水题的垃圾
#include<iostream>//LCA问题(最小公共祖先节点) #include<cstdio>//Tarjan算法变形 #include<vector> #include<cstring> #include<string> #include<algorithm> #include<sstream> using namespace std; const int maxn = 1000 + 15; int n,m; vector<int> Grape[maxn];//树 vector<int> query[maxn]; bool rudu[maxn];//判断入度节点是否为0 int arr[maxn];//公共祖先节点个数 bool vis[maxn]; int father[maxn]; int find(int node) { if(node!=father[node]) father[node] = find(father[node]); return father[node]; } void Tarjan(int u)//从根节点开始搜索 { for(int i=0;i!=Grape[u].size();++i) { int v = Grape[u][i];//相邻节点 Tarjan(v); father[v] = u; } vis[u] = true;//标记节点为根的子树已被访问 for(int i=0;i!=query[u].size();++i) { int v = query[u][i]; if(vis[v])//如果节点已被访问 { int ans = find(v); ++arr[ans]; } } } int main() { while(cin>>n) { memset(rudu,false,sizeof(rudu)); memset(arr,0,sizeof(arr)); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;++i) { Grape[i].clear(); query[i].clear(); father[i] = i; } int u,v,num; char ch; for(int i=0;i!=n;++i) { scanf("%d:(%d)",&u,&num); while(num--) { scanf("%d",&v); Grape[u].push_back(v); rudu[v] = true;//有入度节点存在 } }//建树 scanf("%d",&m); getchar(); for(int i=0;i!=m;++i) { scanf("%1s%d%d%1s",&ch,&u,&v,&ch); query[u].push_back(v); query[v].push_back(u); } for(int v=1;v<=n;++v) if(!rudu[v]) Tarjan(v); for(int i=1;i<=n;++i) { if(arr[i]) cout<<i<<":"<<arr[i]<<endl; } } }

  

不怕万人阻挡,只怕自己投降。
原文地址:https://www.cnblogs.com/newstartCY/p/11588166.html