华师一附中OI组
标题:
P2097 资料分发1
[打印本页]
作者:
admin
时间:
2021-3-30 09:33
标题:
P2097 资料分发1
https://www.luogu.com.cn/problem/P2097
题目描述
有一些电脑,一部分电脑有双向数据线连接。如果一个电脑得到数据,它可以传送到的电脑都可以得到数据。现在,你有这个数据,问你至少将其输入几台电脑,才能使所有电脑得到数据。
输入格式
第一行两个数n,m。n是点数,m是边数。
接下来m行,每行2个整数p,q表示p到q有一条双向数据线。
输出格式
一个整数,表示至少输入的电脑数量。
输入输出样例
输入 #1复制
4 5
1 2
1 3
2 3
2 1
3 4
输出 #1复制
1
说明/提示
对于30%的数据:n<=100,m<=1000
对于60%的数据:n<=2000,m<=100000
对于100%的数据:n<=100000, m<=200000
数据不保证没有重边,不保证没有自回环
作者:
admin
时间:
2021-3-30 09:44
用简单的图的DFS方法,类似种子填充算法来做是可行的。
考察读入建图的基本功和基本的DFS方法。
/// 2097种子填充算法
#include <bits/stdc++.h>
using namespace std;
const int mn=100010;
const int mm=400010; // 双向边注意开2倍
int n,m,cnt;
int nbs[mn],vis[mn];
int ev[mm],nxt[mm]; // eu和ew都无必要
void readmap()
{
int u,v;
cin>>n>>m;
for (int i=1; i<=n; i++) nbs[i]=vis[i]=0;
for (int i=1; i<=m; i++)
{
cin>>u>>v;//双向边
ev[i]=v,nxt[i]=nbs[u],nbs[u]=i;
ev[i+m]=u,nxt[i+m]=nbs[v],nbs[v]=i+m;
}
}
void showmap() //检查建图情况
{
for (int i=1; i<=n; i++)
{
cout<<i<<':';
for (int j=nbs[i]; j; j=nxt[j]) cout<<setw(3)<<ev[j]<<' ';
cout<<endl;
}
}
void dfs(int p)
{
vis[p]=cnt;
for (int i=nbs[p]; i!=0; i=nxt[i])
{
int v=ev[i]; //常规无聊直观操作
if (vis[v]==0)dfs(v);
}
}
void pp()
{
for(int i=1; i<=n; i++) cout<<setw(3)<<vis[i];
cout<<endl;
}
int main()
{
readmap();
//showmap();
cnt=0;
for(int i=1; i<=n; i++)
{
if (vis[i]==0)
{
++cnt;
dfs(i);
}
}
cout<<cnt;
return 0;
}
/*
4 5
1 2
1 3
2 3
2 1
3 4
*/
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2