pat甲级打卡-1013 Battle Over Cities
一题双解:
1.临界矩阵+dfs 查询二维矩阵邻接分量
// 题目要求:output 指定城市沦陷后需要修复的路的条数
// 图的存储,因为要多次查询两节点是否连接,所以用邻接矩阵,相比邻接表的时间更低
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int v[N][N];
bool visited[N];
int n,m,k;
void dfs(int node){
visited[node]=true;
for(int i=1;i<=n;i++){
if(!visited[i] && v[node][i]==1)
dfs(i);
}
}
int main(){
int a,b;
cin>>n>>m>>k;
while(m--){
cin>>a>>b;
v[a][b]=v[b][a]=1;
}
while(k--){
memset(visited,0,sizeof visited);
int id,cnt=0;
cin>>id;
visited[id]=true;
for(int j=1;j<=n;j++){
if(!visited[j]){
dfs(j);
cnt++;
}
}
cout<<cnt-1<<endl;
}
return 0;
}
2.并查集
// 题目要求:output 指定城市沦陷后需要修复的路的条数
//并查集处理连通分量问题
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int v[N][N];//邻接矩阵
int p[N];
int n,m,k;
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void init(){
for(int i=1;i<=n;i++) p[i]=i;
return;
}
void merge(int a,int b){
a=find(a);
b=find(b);
if(a!=b){
p[a]=b;
}
return ;
}
int oper(int x){
int sum=0;
for(int i=0;i<N;i++){//断开与x相连的所有边
for(int j=0;j<N;j++){
if(i!=x && j!=x && v[i][j]==1){
merge(i,j);
}
}
}
for(int i=1;i<=n;i++){
if(p[i]==i) sum++;
}
return sum-2; //除去被占领的节点本身以及n个节点需要n-1条路
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
p[i]=i;
}
while(m--){
int a,b;
cin>>a>>b;
v[a][b]=v[b][a]=1;
}
while(k--){
int id;
cin>>id;
init();
int ans=oper(id);
cout<<ans<<endl;
}
return 0;
}