//并查集代码
zju pat1013 http://pat.zju.edu.cn/contests/pat-a-practise/1013
#include <iostream> using namespace std; int road[500000][2]; int city[1005]; void init_union(int n) { int i; for(i = 1 ;i<=n;i++) city[i] = i; } int find(int x) { int r= x; while(city[r]!=r) //首先找到最顶端的root { r = city[r]; } int i = x; int j; while (i!=r) //压缩路径 { j = city[i]; //依次记录路径上的点,然后分别指向root city[i] = r; i = j; } return r; //返回root } void join(int r[2]){ int fx = find(r[0]); int fy = find(r[1]); if(fx != fy) city[fx] = fy; } int main(){ int n,m,k; int i,j,flag,t; while(cin>>n>>m>>k){ for(i =0;i< m;i++) { cin>>road[i][0]>>road[i][1]; } init_union(n); for(j =0;j<k;j++) { cin>>flag; if(road[j][0]!=flag && road[j][1]!=flag)//去除跟被占领的边 join(road[j]); int num = 0; for(t=1;t<=n;t++) if(city[t]==t) //有多少个圈子,因为被敌人占领那个,也是一个,所以多减了一个, num++; cout<<num-2<<endl; } } return 0; }
//bfs搜索
#include <iostream> #include <string.h> #include <queue> using namespace std; #define N 1001 int main() { int n,m,k,i,j,t,c1,c2; bool ways[N][N]; int concern[N]; memset(ways,false,sizeof(ways)); memset(concern,false,sizeof(concern)); while(cin>>n>>m>>k) { for(i =0;i<m;i++) { cin>>c1>>c2; ways[c1][c2] = true; ways[c2][c1] = true; } for(i =0; i<k;i++) { cin>>concern[i]; } for(i =0;i<k;i++) { int visit[N],count; queue<int>q; memset(visit,false,sizeof(visit)); visit[concern[i]] = true; count =0; for(j =1;j<=n;j++) { if(visit[j]!=true) //bfs { queue<int>dq; visit[j] =1; dq.push(j); while(!dq.empty()) { int temp = dq.front(); dq.pop(); for(t =0;t<=n;t++) //深度搜索,看是否有相连的城市,访问过,则标记 { if(ways[temp][t]&& visit[t]!=1) { dq.push(t); visit[t] = 1; } } } count++; //有多少个圈,孤岛+1 } } cout<<count -1<<endl; } } return 0; }