2017 CCPC Qinhuangdao D

Considering that for a connected block, the last added point must be the point with the largest degree, and the degree is siz-1 of the connected block. The graph after deleting this point, because the degree of each point is reduced by one, still satisfies the above properties. So in turn, we can find that if there is a solution, the scheme of adding the final degree to the graph in order from small to large must be a set of solutions. It can be judged whether this way of adding points is valid. Connectivity is maintained using union queries.

#include <bits/stdc++.h>
using namespace std;
const int maxn=105000;
vector<int>g[maxn], ans[maxn];
int n, m;
int fa[maxn], siz[maxn], id[maxn], degree[maxn];
bool vis[maxn];
bool cmp(int x, int y){
    return degree[x]<degree[y];
}
int f(int x){
    if(x==fa[x])return x;
    return fa[x]=f(fa[x]);
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &m);
        for(int i=1;i<=n;i++){
            g[i].clear();
            ans[i].clear();
            fa[i]=id[i]=i, siz[i]=1;
            degree[i]=0;
            vis[i]=false;
        }
        for(int i=1;i<=m;i++){
            int u, v;
            scanf("%d%d", &u, &v);
            degree[u]++, degree[v]++;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        sort(id+1, id+1+n, cmp);
        //for(int i=1;i<=n;i++)printf("%d%c", id[i], i==n?'\n':' ');
        bool ok=true;
        for(int i=1;i<=n;i++){
            int u=id[i];
            int sum=0;
            vis[u]=true;
            for(int j=0;j<g[u].size();j++){
                int v=g[u][j];
                if(!vis[v])continue;
                sum++;
                v=f(v);
                if(v==u)continue;
                ans[i].push_back(v);
                fa[v]=u;
                siz[u]+=siz[v];
            }
            if(siz[u]!=sum+1){
                ok=false;
                break;
            }
        }
        if(!ok)printf("No\n");
        else {
            printf("Yes\n");
            for(int i=1;i<=n;i++){
                printf("%d %d", id[i], (int)ans[i].size());
                for(int j=0;j<ans[i].size();j++){
                    printf(" %d", ans[i][j]);
                }
                printf("\n");
            }
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325945977&siteId=291194637