例子1:连通块的数量
思路:
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
vector<int> G[20005];//!!!size问题
bool vis[20005];//!!!size问题
void dfs(int u) {
vis[u] = true;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (!vis[v]) {
dfs(v);
}
}
}
int main() {
freopen("block.in","r",stdin);
freopen("block.out","w",stdout);
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
int cnt=0;
for(int i=1;i<=n;i++){
if(!vis[i]){//边判断有无访问过,边进行搜索
cnt++;
dfs(i);
}
}
cout<<cnt<<endl;
return 0;
}
例子2:下午茶时间
思路:
#include<iostream>
#include<cstdio>
using namespace std;
int f[50005];
int getf(int v)
{
return f[v]==v ? v:getf(f[v]);
}
void merge(int v,int u)
{
int t1=getf(v);
int t2=getf(u);
if(t1!=t2)
f[t2]=t1;
return;
}
int main()
{
freopen("tea.in","r",stdin);
freopen("tea.out","w",stdout);
int i,x,y,n,m,s;
while(scanf("%d %d %d", &n,&m,&s)!=EOF)
{
for(i=1; i<=n; i++)
f[i]=i;
for(i=1; i<=m;i++)
{
scanf("%d %d", &x,&y);
merge(x,y);
}
for(i=1; i<=s; i++)
{
scanf("%d %d", &x,&y);
if(getf(x)==getf(y))
printf("Y\n");
else
printf("N\n");
}
}
return 0;
}
例子3:家谱
思路:
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> son[100005];
int ans[100005];
bool vis[100005];
int dfs(int x){//dfs函数返回x节点的直系后代数
int res=0;
for(int i=0;i<son[x].size();i++){
res+=dfs(son[x][i]);//遍历x节点的所有儿子,求出所有的儿子的直系后代数
}
ans[x]=res;
return res+1;//x的孩子的直系后代数+1
}
int main(){
freopen("family.in","r",stdin);
freopen("family.out","w",stdout);
cin>>n;
for(int i=0;i<n-1;i++){
int x,y;
cin>>x>>y;
son[x].push_back(y);//x的孩子为y
vis[y]=true;//y有父亲,标记为true,表示不是根节点
}
int u;
for(int i=1;i<=n;i++){//找根节点
if(!vis[i]){
u=i;
break;
}
}
dfs(u);
for(int i=1;i<=n;i++){
cout<<ans[i]<<endl;
}
return 0;
}
例子4:联合权值(选做)
思路:
#include<bits/stdc++.h>
#define ll long long
#define MAXN 500010
#define N 201
#define INF 0x3f3f3f3f
#define gtc() getchar()
using namespace std;
template <class T>
inline void read(T &s){
s = 0; T w = 1, ch = gtc();
while(!isdigit(ch)){if(ch == '-') w = -1; ch = gtc();}
while(isdigit(ch)){s = s * 10 + ch - '0'; ch = gtc();}
s *= w;
}
template <class T>
inline void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x/10);
putchar(x % 10 + '0');
}
const int mod = 10007;
struct node{
int y, ne;
}e[MAXN];
int lin[MAXN], len = 0;
inline void add(int x, int y){
e[++len].y = y, e[len].ne = lin[x], lin[x] = len;
}
int n;
int d[MAXN];
int sum[MAXN];
int all = 0, ans = 0;
void bfs(int x){
int fmx = 0, smx = 0;
int sum1 = 0, sum2 = 0;
for(int i = lin[x]; i; i = e[i].ne){
int y = e[i].y;
// printf("%d ", y);
sum1 = (sum1 + d[y]) % mod;
sum2 = (sum2 + d[y] * d[y]) % mod;
if(d[y] > fmx){
smx = fmx, fmx = d[y];
}
else if(d[y] > smx) smx = d[y];
}
// puts("");
ans = max(ans, fmx * smx);
sum1 = sum1 * sum1 % mod;
all += (sum1 - sum2 + mod) % mod;
}
int main()
{
freopen("link.in","r",stdin);
freopen("link.out","w",stdout);
read(n);
int x, y;
for(int i = 1; i < n; ++i){
read(x), read(y);
add(x, y), add(y, x);
}
for(int i = 1; i <= n; ++i) read(d[i]);
for(int i = 1; i <= n; ++i) bfs(i);
all %= mod;
cout << ans << ' ' << all << endl;
return 0;
}