就是找总共有多少个球星,可以用并查集或者targin就强连通分量有多少个
targin的
#include<bits/stdc++.h>
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
const int N=1e5+7;
int pre[N];
int find(int x)
{
return x==pre[x]?x:pre[x]=find(pre[x]);
}
void Union(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y)
pre[x]=y;
}
using namespace std;
int main()
{
int n,m,x,y;
scff(n,m);
for(int i=1;i<=n;i++) pre[i]=i;
while(m--)
{
scff(x,y);
Union(y,x);
}
int sum=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
sum++;
}
cout<<sum;
return 0;
}
targin的
#include<bits/stdc++.h>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
#define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define vi vector<int>
#define mp make_pair
#define pf printf
#define prf(x) printf("%d
",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const double eps=1e-6;
const double pi=acos(-1.0);
const int inf=0xfffffff;
const int N=1e5+7;
struct Edge {
int v,next;
}edge[5*N];
int dfn[N],low[N];
int stackk[N],node[N],visit[N],cnt,tot,qqq;
int belong[N],bcnt;
void add_edge(int x,int y)
{
edge[cnt].next=node[x];
edge[cnt].v = y;
node[x]=cnt++;
return ;
}
void tarjan(int x)//代表第几个点在处理。递归的是点。
{
dfn[x]=low[x]=++tot;// 新进点的初始化。
stackk[++qqq]=x;//进站
visit[x]=1;//表示在栈里
for(int i=node[x];i!=-1;i=edge[i].next)
{
if(!dfn[edge[i].v]) {//如果没访问过
tarjan(edge[i].v);//往下进行延伸,开始递归
low[x]=min(low[x],low[edge[i].v]);//递归出来,比较谁是谁的儿子
//父亲,就是树的对应关系,涉及到强连通分量子树最小根的事情。
}
else if(visit[edge[i].v ]){ //如果访问过,并且还在栈里。
low[x]=min(low[x],dfn[edge[i].v]);//比较谁是谁的儿子/父亲。就是链接对应关系
}
}
if(low[x]==dfn[x]) //发现是整个强连通分量子树里的最小根。
{
bcnt++;
do{
belong[stackk[qqq]]=bcnt;
visit[stackk[qqq]]=0;
qqq--;
}while(x!=stackk[qqq+1]);//出栈,并且输出。
}
return ;
}
int in[N],out[N],num[N];
void solve(int n)
{
tot=qqq=bcnt=0;
mm(dfn,0);
mm(low,0);
mm(belong,0);
mm(in,0);
mm(out,0);
mm(visit,0);
mm(num,0);
rep(i,1,n+1)
if(!dfn[i])
tarjan(i);
int ans1=0,ans2=0;
rep(i,1,n+1)
{
num[belong[i]]++;
for(int j=node[i];j!=-1;j=edge[j].next)//计算入度和出度
{
if(belong[i]!=belong[edge[j].v])
{
in[belong[edge[j].v]]++;
out[belong[i]]++;
}
}
}
}
//这个放在main里面
int main()
{
mm(node,-1);
int n,m;
scff(n,m);
while(m--)
{
int x,y;scff(x,y);
add_edge(x,y);
add_edge(y,x);
}
solve(n);
prf(bcnt);
return 0;
}