题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2463
题意:
含有n(从1到n)个电脑的网络,其中第一台电脑为服务器,其他的电脑一开始均和它连通。有m条边,每一条边有a和b,表示a和b之间不再连通(其为双向连通),问最后还有几个电脑与服务器连通。
题解:
简单的BFS, 但是这里需要考虑两个问题。
1.数据的范围比较大,如果直接开二位数组来进行建图的话,会爆空间的,所以这里我是用vector来做的。
2.直接调用STL的队列的话,会出现超时的情况,这里建议自己手写队列,这样会节省很多的时间。
代码:
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
const int maxn = 1e4+10;
typedef long long ll;
vector<int>num[maxn];
int visited[maxn];
int pre[maxn];
int n,m;
class queue
{
private:
int start,end;
int arr[10010];
public:
void clear()
{
start = 0;
end = 0;
}
int front()
{
return arr[start];
}
bool empty()
{
return end == start;
}
void push(int n)
{
arr[end++] = n;
}
void pop()
{
start++;
}
};
int bfs(int x)
{
met(visited,0);
met(pre,0);
queue q;
visited[1]=1;
q.push(1);
int cnt=0;
while(!q.empty())
{
int y=q.front();
q.pop();
for(int i=0;i<num[y].size();i++)
pre[num[y][i]]=y;
for(int i=1;i<=n;i++)
{
if(!visited[i]&&pre[i]!=y)
{
visited[i]=1;
q.push(i);
cnt++;
}
}
}
return cnt;
}
int main()
{
int cnt=1;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0||m==0)
break;
for(int i=1;i<=n;i++)
num[i].clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
num[x].push_back(y);
num[y].push_back(x);
}
int temp=bfs(1);
printf("Case %d: %d\n",cnt++,temp);
}
}