2019 summer training camp 8.23 (problem2.party)

For the first point of degree less than d deleted after deleting the others point d to less than the degree of change is also omitted, and finally find the maximum link block.

It can be used to store the stack when the puncturing point, the degree less than d are pushed onto the stack, to ensure that the point will be less than d omitted.

Finally, find the maximum block communication with disjoint-set can be achieved.

note! Finally, people are being invited to direct or indirect Unicom, China Unicom is drawing so without the presence of a middle person was not invited, but the relationship between man and he has been invited, this relationship only invited the people reflect ( I would be wrong in this, the topic would like complicated).

#include<bits/stdc++.h>
#define N 200002
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
struct EDGE{
    int nextt,to,me;
}w[N*2];
int tot=0,head[N],vis[N],fa[N],du[N],sum[N],n,d;
queue<int>q;
void add(int a,int b)
{
    tot++;
    w[tot].nextt=head[a];
    w[tot].me=a;
    w[tot].to=b;
    head[a]=tot;
} 
Void Work () // deleting degree point less than d 
{
     for ( int I = . 1 ; I <= n-; ++ I)
       IF (du [I] <d) q.push (I), VIS [I ] = . 1 ;
     the while (! q.empty ()) 
    { 
        int X = q.front (); q.pop ();
         for ( int I = head [X]; I; I = W [I] .nextt) 
        { 
            int V = W [I] .to; 
            du [V] - ;
             IF (! du [V] <&& VIS D [V]) q.push (V), VIS [V] = . 1 ; // remember marked Signs have been removed
         }
    }
}
int get(int x)
{
    if(fa[x]==x)return x;
    return fa[x]=get(fa[x]);
}
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    n=read();int m=read();d=read();
    int maxx=0;
    for(int i=1;i<=m;++i)
    {
        int a=read(),b=read();
        du[a]++;du[b]++;
        add(a,b);add(b,a);
    }
    for(int i=1;i<=n;++i)
      fa[i]=i,sum[i]=1;
    work();
    int id;
    for(int i=1;i<=tot;++i)//找出最大的连通块,可用并查集记录 
    {
        if(du[w[i].me]>=d&&du[w[i].to]>=d)
        {
            int f1=get(w[i].me),f2=get(w[i].to);
            if(f1==f2)continue;
            fa[f1]=f2;
            sum[f2]+=sum[f1];
            if(sum[f2]>maxx)maxx=sum[f2],id=f2;
        }
    }
    printf("%d\n",maxx);
    for(int i=1;i<=n;++i)
      if(get(i)==id)printf("%d ",i);
} 
/*
4 4 2
1 2
2 3
3 4
4 2

5 4 3
1 2
1 3
1 4
1 5

11 9 1
1 2
1 3
1 4
1 5
6 7
6 8
6 9
6 10
6 11
*/
View Code

 

Guess you like

Origin www.cnblogs.com/yyys-/p/11402122.html