Zoj 3811并查集
2016-03-16 19:34
309 查看
14年网络赛一道题,有了思路敲起来还是挺流畅了,题目可以理解为不停的添加关键点到图里,然后判断连通性,所以想到了并查集,先把关键点存起来,然后依次进行合并。代码如下,1A还是很高兴的。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
vector<int> bcj[100005];
vector<int> L;
int in[100005];
int fa[100005];
int n,m,k,l;
int init(){
for(int i=0;i<=n;i++)
fa[i]=i;
}
int fin(int x){
int r=x;
while(fa[r]!=r){
r=fa[r];
}
return r;
}
void modi(int x,int y){
int fx=fin(x);
int fy=fin(y);
if(fx!=fy){
if(fx>fy)
fa[fx]=fy;
else
fa[fy]=fx;
}
}
int main()
{
int t;
cin>>t;
while(t--){
cin>>n>>m>>k;
int x;
L.clear();
memset(in,0,sizeof(in));
memset(fa,0,sizeof(fa));
for(int i=0;i<=n;i++)
bcj[i].clear();
for(int i=0;i<k;i++){
scanf("%d",&x);
in[x]=1;
}
int a,b;
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
bcj[a].push_back(b);
bcj[b].push_back(a);
}
int l;
cin>>l;
for(int i=0;i<l;i++){
scanf("%d",&x);
L.push_back(x);
}
if(l!=k){
cout<<"No\n";
continue;
}
init();
for(int i=1;i<=n;i++){
if(in[i]!=1){
for(int j=0;j<bcj[i].size();j++){
if(in[bcj[i][j]]!=1)
modi(i,bcj[i][j]);
}
}
}
in[L[0]]=0;
for(int i=0;i<bcj[L[0]].size();i++){
if(in[bcj[L[0]][i]]!=1)
modi(L[0],bcj[L[0]][i]);
}
int bo=1;
for(int i=1;i<l;i++){
in[L[i]]=0;
for(int j=0;j<bcj[L[i]].size();j++){
if(in[bcj[L[i]][j]]!=1)
modi(L[i],bcj[L[i]][j]);
}
if(fin(L[i-1])!=fin(L[i])){
bo=0;
break;
}
}
for(int i=1;i<=n;i++){
fa[i]=fin(i);
}
for(int i=2;i<=n;i++){
if(fa[i]!=fa[i-1]){
bo=0;
break;
}
}
if(bo==0){
cout<<"No\n";
}
else{
cout<<"Yes\n";
}
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
vector<int> bcj[100005];
vector<int> L;
int in[100005];
int fa[100005];
int n,m,k,l;
int init(){
for(int i=0;i<=n;i++)
fa[i]=i;
}
int fin(int x){
int r=x;
while(fa[r]!=r){
r=fa[r];
}
return r;
}
void modi(int x,int y){
int fx=fin(x);
int fy=fin(y);
if(fx!=fy){
if(fx>fy)
fa[fx]=fy;
else
fa[fy]=fx;
}
}
int main()
{
int t;
cin>>t;
while(t--){
cin>>n>>m>>k;
int x;
L.clear();
memset(in,0,sizeof(in));
memset(fa,0,sizeof(fa));
for(int i=0;i<=n;i++)
bcj[i].clear();
for(int i=0;i<k;i++){
scanf("%d",&x);
in[x]=1;
}
int a,b;
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
bcj[a].push_back(b);
bcj[b].push_back(a);
}
int l;
cin>>l;
for(int i=0;i<l;i++){
scanf("%d",&x);
L.push_back(x);
}
if(l!=k){
cout<<"No\n";
continue;
}
init();
for(int i=1;i<=n;i++){
if(in[i]!=1){
for(int j=0;j<bcj[i].size();j++){
if(in[bcj[i][j]]!=1)
modi(i,bcj[i][j]);
}
}
}
in[L[0]]=0;
for(int i=0;i<bcj[L[0]].size();i++){
if(in[bcj[L[0]][i]]!=1)
modi(L[0],bcj[L[0]][i]);
}
int bo=1;
for(int i=1;i<l;i++){
in[L[i]]=0;
for(int j=0;j<bcj[L[i]].size();j++){
if(in[bcj[L[i]][j]]!=1)
modi(L[i],bcj[L[i]][j]);
}
if(fin(L[i-1])!=fin(L[i])){
bo=0;
break;
}
}
for(int i=1;i<=n;i++){
fa[i]=fin(i);
}
for(int i=2;i<=n;i++){
if(fa[i]!=fa[i-1]){
bo=0;
break;
}
}
if(bo==0){
cout<<"No\n";
}
else{
cout<<"Yes\n";
}
}
return 0;
}
相关文章推荐
- 方法重载
- 终于忍不住要离职了
- 九度题目1047素数判定
- ICE介绍 (RFC 5245)
- 吃糖果
- DELL R730安装xenserver 6.2,raid卡驱动问题
- 软考信息系统监理师2016年3月15日作业
- 20.leetcode题目67: Add Binary
- unix环境高级编程-unix的进程环境
- 设计模式系列(四)——装饰模式
- MQTT协议详解二
- 图像增强算法实现--直方图的均衡化
- Dockerfile命令介绍及实例
- WAB开发构建概述
- CSS之切出横幅
- 使用TextView实现跑马灯效果
- hdu1003 最大子数组
- 有人(甚至国家)兜底就安全了吗?瑞士央行风暴小议。
- CSS之切出横幅
- CPU Affinity (CPU亲合力)