pat 1021. Deepest Root (并查集,搜索)
2014-10-14 19:57
399 查看
此题首先想到用并查集,然后如果是树再用搜索,但是单独用dfs或bfs也是可以的
并查集注意路径压缩和按秩合并。图方面根据并查集直接能求得连通分支数。
树方面,最后的答案是首先从任意点P1出发dfs,求出最远点集合S1,再从S1中任意点P2出发,求出最远点集合S2。S1并S2即为答案。
point:N=1时可单独处理。不能用二维数组储存边,内存会不够。本身是稀疏矩阵也应当用线性存储,我这里是先排序后再存储的,可以提速。
代码:
并查集和dfs还是要写得熟练
并查集注意路径压缩和按秩合并。图方面根据并查集直接能求得连通分支数。
树方面,最后的答案是首先从任意点P1出发dfs,求出最远点集合S1,再从S1中任意点P2出发,求出最远点集合S2。S1并S2即为答案。
point:N=1时可单独处理。不能用二维数组储存边,内存会不够。本身是稀疏矩阵也应当用线性存储,我这里是先排序后再存储的,可以提速。
代码:
#include<stdio.h> #include<stack> #include<set> #include<map> using namespace std; const int MAX=10005; int n; int uf[MAX]; int ranka[MAX]; int link[3][MAX]; int vis[MAX]; void makeset() { for(int i=1;i<=n;i++) uf[i]=i; } int find(int x) { if(x!=uf[x]) uf[x]=find(uf[x]); return uf[x]; } void un(int x,int y) { int f1 = find(x); int f2 = find(y); if (ranka[f1] < ranka[f2]) { uf[f1]=f2; } else if (ranka[f1] == ranka[f2]) { uf[f1]=f2; ranka[f2]++; } else { uf[f2]=f1; } } stack<int> sta; set<int> res; int minnum=0; void dfs(int start,int len) { sta.push(start); if(len>minnum) { minnum=len; res.clear(); res.insert(start); } if(len==minnum) { res.insert(start); } int i,j; for(i=1;i<=n;i++) { if(link[0][i]<start) { if(link[1][i]==start) { if(!link[2][i]) { link[2][i]=1; dfs(link[0][i],len+1); link[2][i]=0; } } } else if(link[0][i]==start) { if(!link[2][i]) { link[2][i]=1; dfs(link[1][i],len+1); link[2][i]=0; } } else break; } sta.pop(); } int main() { scanf("%d",&n); int x,y; makeset(); multimap<int,int> mpp; multimap<int,int>::iterator mp; for(int i=1;i<n;i++) { scanf("%d %d",&x,&y); if(x<y) mpp.insert(make_pair(x,y)); else mpp.insert(make_pair(y,x)); un(x,y); } if(n==1) { printf("1\n"); return 0; } int sum=0; for(int i2=1;i2<=n;i2++) if(i2==uf[i2]) sum++; if(sum>1) printf("Error: %d components\n",sum); else { int i3=1; for(mp=mpp.begin();mp!=mpp.end();++mp,i3++) { link[0][i3]=mp->first; link[1][i3]=mp->second; } dfs(1,0); set<int> s2=res; res.clear(); minnum=0; dfs(*s2.begin(),0); set<int>::iterator sp; for(sp=res.begin();sp!=res.end();++sp) s2.insert(*sp); for(sp=s2.begin();sp!=s2.end();++sp) printf("%d\n",*sp); } return 0; }
并查集和dfs还是要写得熟练
相关文章推荐
- PAT 1013 Battle Over Cities(并查集)
- PAT 甲级 1021 Deepest Root (并查集,树的遍历)
- PAT - L2-010. 排座位(并查集)
- 搜索或者并查集 问题 G: 水果消除
- PAT--哥尼斯堡的“七桥问题”--深度搜索
- PAT - 天梯赛 L2-024 部落 (并查集)
- hdu 4619 warm up 2 并查集或搜索都可以做出来的题 2013多校联合训练第二场
- 1114. Family Property (25)(PAT 并查集)
- PAT甲题题解-1107. Social Clusters (30)-PAT甲级真题(并查集)
- PAT - 甲级 - 1114. Family Property (25) (并查集)
- hdu 2818 Building Block 并查集(边搜索边更新)
- pat 搜索树判断
- PAT 数据结构 05-图1. List Components (25) 深度搜索DFS和广度搜索BFS
- PAT 1039. Course List for Student (25)(倒搜索,注意scanf和string时间消耗大)
- PAT 甲级 1021 Deepest Root (并查集,树的遍历)
- pat L3-008 DFS深度优先搜索
- PAT (Advanced Level) Practise 1107. Social Clusters (30) 并查集
- PAT4-06. 搜索树判断
- PAT L2-007. 家庭房产 并查集+父子关系数据更新
- PAT L2-010. 排座位 疑似种类并查集