图论
并查集:
#include<iostream> using namespace std; int father[5001]; int n,m,p; int find(int x) { if(father[x]!=x)//路径压缩优化 father[x]=find(father[x]);//把路上的所有点祖先全部改掉 return father[x]; } void unionn(int x,int y) { father[y]=x;//y的祖先为x的祖先 //相当于合并祖先 } int main() { cin>>n>>m>>p; for(int i=1;i<=n;i++) { father[i]=i;//所有数据初始祖先为自己 //独立的一个数为一个集合 } for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; int r1,r2; r1=find(x); r2=find(y);//寻找两个数的祖先 if(r1!=r2)//如果不是同一个祖先 { unionn(r1,r2);//合并 } } for(int i=1;i<=p;i++) { int x,y; cin>>x>>y; if(find(x)==find(y))//如果是同一个祖先 { cout<<"Yes"<<endl;//是 } else cout<<"No"<<endl;//否 } }
题目号 | 题目名 | 注释 |
洛谷P3367 | 【模板】并查集 | 如题 |
洛谷P2024 | 【NOI2001】食物链 |
搞好三者关系 |
洛谷P1525 | 关押罪犯 |
排序+并查集 |
洛谷P1111 | 修复公路 |
eazy |
洛谷P1197 | 【JSOI2008】星球大战 |
逆向思维 |