并查集/DFS——BZOJ1529/Luogu3420 [POI2005]SKA-Piggy Banks

来源:互联网 发布:table js表格数据合计 编辑:程序博客网 时间:2024/05/16 06:04

http://www.lydsy.com/JudgeOnline/problem.php?id=1529
https://www.luogu.org/problem/show?pid=3420
从POI找到一题比较水的。。。
题目意思其实可以很快的转化成求连通块个数
所以我们可以用灌水或者并查集很快地解决
先贴并查集:

#include<bits/stdc++.h>using namespace std;int fa[1000001];inline int getfather(int v){    if(fa[v]==v)return v;    fa[v]=getfather(fa[v]);    return fa[v];}int main(){    int n,ans;scanf("%d",&n);    for(int i=1;i<=n;i++)fa[i]=i;    ans=n;//一开始假设全砸    for(int i=1;i<=n;i++){        int x;scanf("%d",&x);        int xx=getfather(i),yy=getfather(x);        if(xx==yy)continue;        ans--;//合并同一连通块少砸一个        fa[xx]=yy;    }    printf("%d",ans);    return 0;}

最后贴dfs灌水的(为什么我感觉比并查集要好理解。。。)

#include<bits/stdc++.h>using namespace std;int nedge=0,p[2000001],nex[2000001],head[2000001];bool b[1000001]={0};inline void addedge(int a,int b){    p[++nedge]=b;nex[nedge]=head[a];    head[a]=nedge;}inline void dfs(int x){    b[x]=1;    for(int k=head[x];k;k=nex[k])if(!b[p[k]])dfs(p[k]);}int main(){    int n,ans=0;scanf("%d",&n);    for(int i=1;i<=n;i++){        int x;scanf("%d",&x);        addedge(i,x);addedge(x,i);    }    for(int i=1;i<=n;i++)if(!b[i]){        ans++;//连通块数+1        dfs(i);    }    printf("%d",ans);    return 0;}
1 0
原创粉丝点击