题目:Battle Over Cities
我的代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
//返回值为群的个数
int BFS(int edge[1001][1001],int visited[],int v){
int h = 0;
queue<int>q;
for(int i = 1;i <= v;i++){
if(visited[i] == 0){ //找没遍历过的,开始第二个群
q.push(i);
while(!q.empty()){
int p = q.front();
visited[p] = 1;
q.pop();
for(int j = 1;j <= v;j++){
if(edge[p][j] == 1 && visited[j] == 0) q.push(j);
}
}
h++;
}
}
return h;
}
void DFS(int v,int edge[1001][1001],int visited[],int vi){
visited[vi] = 1;
for(int i = 1;i <= v;i++){
if(edge[vi][i] == 1 && visited[i] == 0){
DFS(v,edge,visited,i);
}
}
}
int DFSTravle(int edge[1001][1001],int visited[],int v){
int h = 0;
for(int i = 1;i <= v;i++){
if(visited[i] == 0) {
DFS(v,edge,visited,i);
h++;
}
}
return h;
}
int main(){
int v,e,t,h = 0; //h为群的个数
int edge[1001][1001] = {0}; //每个顶点涉及的边数
int visited[1001] = {0};
cin>>v>>e>>t;
if(v == 0){
cout<<0<<endl;
return 0;
}
if(v == 1){
cout<<0<<endl;
return 0;
}
for(int i = 0;i < e;i++){
int a,b;
cin>>a>>b;
edge[a][b] = edge[b][a] = 1;
}
//用划分联通集的方法来判断还需要构造多少条边,若有n个群,则需要n-1条边(BFS)
for(int i = 0;i < t;i++){
int m;
cin>>m;
fill(visited,visited+1001,0);
visited[m] = 1; //判断联通集的时候跳过m,避免需要更改edge矩阵
//cout<< BFS(edge,visited,v) - 1<<endl;
cout<< DFSTravle(edge,visited,v) - 1<<endl;
}
return 0;
}
参考代码:
链接:https://www.nowcoder.com/questionTerminal/eede8748219f485ebd9c9a268bb45b23
来源:牛客网
//并查集实现较为简单且高效
#include <set>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1000 + 10;
struct Edge
{
int p1, p2;
Edge(int u, int v):p1(u), p2(v) {}
};
set<int> block;
vector<Edge> edges;
int p[maxn];
int find_sym(int x){
return (p[x] == x)? x : (p[x] = find_sym(p[x]));
}
int main(){
int n, m, k;
scanf("%d %d %d", &n, &m, &k);
for(int i=0;i<m;i++){
int u, v;
scanf("%d %d", &u, &v);
edges.push_back(Edge(u, v));
}
for(int i=0;i<k;i++){
int lost_city;
scanf("%d", &lost_city);
block.clear();
memset(p, 0, sizeof(p));
for(int j=1;j<=n;j++) p[j] = j;
for(int h=0;h<m;h++){
Edge e = edges[h];
if(e.p1==lost_city || e.p2==lost_city) continue;
else{
int x = find_sym(e.p1);
int y = find_sym(e.p2);
if(x!=y) p[x] = y;
}
}
for(int j=1;j<=n;j++){
int symbol = find_sym(j);
if(!block.count(symbol)) block.insert(symbol);
}
cout << block.size()-2 << endl;
}
return 0;
}
评注:
参考代码用了并查集,自己的博文算法收藏有相关帖子
应试的时候,用全局变量的确比传函数要来的方便,不过在实际项目中就不建议用了。