12.2球迷

就是找总共有多少个球星,可以用并查集或者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\n",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;
}

猜你喜欢

转载自www.cnblogs.com/wzl19981116/p/10087408.html