Summer exams 2: party party (like topology + tarjan)

topic:

analysis:

If no: each invited further understanding directly least d invited person, then this limitation, directly seeking the maximum run tarjan communication block.

After the addition of this limit, obviously some points are not in line, we can consider these points and then delete the run tarjan.

A point is less than the degree d, is not satisfied, the edge will be connected thereto are deleted. But this point will lead connected thereto is omitted because it is this edge with the same condition is not satisfied, and need to be deleted.

So you can use a queue to be deleted to save the point , it is not very familiar with, right, much like topology, but only the topology of the enqueue is 0, and where d is smaller than the penetration enqueued

#include<bits/stdc++.h>
using namespace std;
#define N 200005
int cnt=0,vis[N],T=0,bel[N],low[N],stk[N],num[N],top=0,minn[N],n,d,m;
bool fl[N];
int to[N<<1],nex[N<<1],head[N],tot=0,w[N<<1],du[N];
void add(int a,int b){ to[++tot]=b; nex[tot]=head[a]; head[a]=tot; }
vector<int>kk[N];
void tarjan(int x)
{
    vis[x]=low[x]=++T;
    stk[++top]=x; fl[x]=true;
    for(int i=head[x];i;i=nex[i]){
        if(w[i]==-1) continue;
        int v=to[i];
        if(!vis[v]){ tarjan(v); low[x]=min(low[x],low[v]); }
        else if(fl[v]) low[x]=min(low[x],vis[v]);
    }
    if(vis[x]==low[x]){
        cnt++;
        do{
            fl[stk[top]]=false; bel[stk[top]]=cnt;
            kk[cnt].push_back(stk[top]); 
            num[cnt]++; minn[cnt]=min(minn[cnt],stk[top]);
        }while(stk[top--]!=x);
    }
}
void work()
{
    queue<int>q;
    for(int i=1;i<=n;i++) if(du[i]<d) q.push(i);
    while(!q.empty()){
        int u=q.front(); q.pop();
        for(int i=head[u];i;i=nex[i]){
            int v=to[i];
            if(w[i]==-1) continue;
            du[v]--; w[i]=-1;
            if(du[v]<d) q.push(v);
        }
    }
}
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    int a,b;
    scanf("%d%d%d",&n,&m,&d);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a,&b);
        add(a,b); add(b,a);
        du[a]++; du[b]++;
    }
    work();
    memset(minn,0x7f7f7f,sizeof(minn));
    for(int i=1;i<=n;i++)
    if(!vis[i]) tarjan(i);
    int ans=0,mn=0x7f7f7f;
    for(int i=1;i<=cnt;i++)
    if(num[i]>num[ans]||(num[i]==num[ans]&&minn[i]<mn)) mn=minn[i],ans=i;
    printf("%d\n",num[ans]);
    for(int i=1;i<=n;i++)
    if(bel[i]==ans) printf("%d ",i);
}
/*
18 25 3
9 11
1 15
13 15
3 1
7 16
11 13
17 6
3 13
5 1
7 2
4 15
7 6
11 3
5 10
9 16
6 5
7 1
7 3
17 16
1 7
3 1
5 8
3 9
3 7
1 12

*/

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11402303.html