ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【刷题】Serval and Essay

2022-09-14 22:30:31  阅读:200  来源: 互联网

标签:Essay return int Serval fa 刷题 now find size


题目地址:J-Serval and Essay_"蔚来杯"2022牛客暑期多校训练营1 (nowcoder.com)
题意:
  有一张n个点m条边的无重边无自环的有向图
  初始时可以选择一个点染黑,其余点均为白色
  若某个点的所有边的起点都是黑点,则该点可以被染黑
  最大化图中黑点的数量
  多组数据,n <= 2e5 m <= 2e5

题型:启发式合并

代码以及注释:

#include<bits/stdc++.h>
using namespace std;

//点的合并:
//    将所有入度为1的点与他的前驱合并 
//    然后反复合并

const int N=2e5+10;
int n,m;
set <int > fr[N],to[N];
int fa[N],sz[N]; 

struct node
{ int a,b; };

int find(int x)     //类似于并查集的点集合并 
{
    if(x != fa[x] ) return fa[x] = find(fa[x]);
    return fa[x];
}

void merge(int x,int y)
{
    x=find(x),y=find(y);
    if(x==y ) return;
    //启发式合并的本质:将size小的合并到size大的上 
    if(to[x].size() > to[y].size() )
        swap(x,y);
    
    //将x合并到y上 
    fa[x]=y; 
    sz[y] += sz[x];
    vector <node > v;
    
    //使用增强for的方法,遍历set 
    for(int now : to[x])
    {
        to[y].insert(now);
        fr[now].insert(y);
        fr[now].erase(x);
        
        if(fr[now].size()==1 )
             v.push_back(node{now,y});
    }
    
    int v_size=v.size(); 
    for(int i=0;i<v_size;i++)
        merge(v[i].a,v[i].b);
}

void clear_and_input()
{
    scanf("%d",&n);
    
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;
        sz[i]=1;
        to[i].clear();
        fr[i].clear();
    }
    
    for(int i=1;i<=n;i++)
    {
        int k,x;
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d",&x);     //添加x到i的一条边 
            to[x].insert(i);
            fr[i].insert(x);
        }
    }
}

void suodian()
{
    for(int i=1;i<=n;i++)
    {
         if(fr[i].size() == 1 )
         {    
             //从set中取出元素!!! 
             int x = *fr[i].begin() , y=i;
            merge(x,y);
        }
    }
}

void count()
{
    int ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,sz[i]); 
    printf("%d\n",ans);
} 

int main()
{
    int T,cas=0;
    cin>>T;
    while(T--)
    {
         clear_and_input();
         suodian();
         printf("Case #%d:",++cas);
         count();
    }
    
    return 0;
} 

 

PS:bitset实际上是若干个long long连接实现的,不过是位运算较快

PS:使用增强for的方式遍历set

set <node > s;

for(node now : s )

 

标签:Essay,return,int,Serval,fa,刷题,now,find,size
来源: https://www.cnblogs.com/xwww666666/p/16694861.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有