思路:
通过 并查集基本操作(GetPre Merge)求图的连通分量个数-1 即为所要修建的数量
#include<iostream>
#include<fstream>
using namespace std;
const int Size=1010;
struct node
{
int x, y;
}Nodes[Size*Size];
int Pre[Size];
void Init(int N)
{
for(int i=1; i<=N; i++)
Pre[i]=i;
}
int GetPre(int a)
{
if(Pre[a]!=a)
Pre[a]=GetPre(Pre[a]);
return Pre[a];
}
void Merge(int a, int b)
{
int p1=GetPre(a);
int p2=GetPre(b);
if(p1!=p2)
Pre[p1]=p2;
}
int main()
{
//ifstream cin("test.txt");
int N, M, K;
cin>>N>>M>>K;
for(int i=0; i<M; i++)
{
cin>>Nodes[i].x>>Nodes[i].y;
}
while(K--)
{
int num;
cin>>num;
Init(N);
for(int i=0; i<M; i++)
{
if(Nodes[i].x==num||Nodes[i].y==num)
continue;
Merge(Nodes[i].x,Nodes[i].y);
}
int ans=0;
for(int i=1; i<=N; i++)
{
if(i==num)
continue;
if(Pre[i]==i)
ans++;
}
cout<<ans-1<<endl;
}
return 0;
}
DFS版本
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
const int Size=1010;
int edge[Size][Size];
int visited[Size];
int K, M, N;
void dfs(int i)
{
visited[i]=1;
for(int j=1; j<=N; j++)
{
if(!visited[j]&&edge[i][j])
dfs(j);
}
}
int main()
{
//ifstream cin("test.txt");
memset(edge, 0, sizeof(edge));
cin>>N>>M>>K;
for(int i=0,a, b; i<M; i++)
{
cin>>a>>b;
edge[a][b]=edge[b][a]=1;
}
int tmp;
while(K--)
{
cin>>tmp;
memset(visited, 0, sizeof(visited));
int ans=0;
visited[tmp]=1;
for(int i=1; i<=N; i++)
{
if(!visited[i])
{
dfs(i);
ans++;
}
}
cout<<ans-1<<endl;
}
return 0;
}
BFS : 最后一个测试点超时 其他测试点正确 目前想不到还有什么剪枝了···
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int Size=1010;
int edge[Size][Size];
int K, M, N;
int visited[Size];
int main()
{
memset(edge,0,sizeof(edge));
cin>>N>>M>>K;
for(int i=0,a,b; i<M; i++)
{
cin>>a>>b;
edge[a][b]=edge[b][a]=1;
}
int tmp;
queue<int>que;
while(K--)
{
cin>>tmp;
memset(visited,0,sizeof(visited));
int ans=0;
visited[tmp]=1;
for(int i=1; i<=N; i++)
{
if(!visited[i])
{
que.push(i);
while(!que.empty())
{
int j=que.front();
que.pop();
visited[j]=1;
for(int k=1; k<=N; k++)
if(!visited[k]&&edge[j][k])
que.push(k);
}
ans++;
}
}
cout<<ans-1<<endl;
}
return 0;
}