2017 CCPC秦皇岛 D.Graph Generator

题目链接

度数大的点肯定时后加进去的。那么按度数小的顺序加可能是一组合法解(图有解的情况下肯定是合法解)。并查集维护连通性,每次看连出去的边和图中存在的边的数量是否合法。就对了…看了别的网友写的可撤销并查集维护感觉是一个道理但是麻烦很多。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int f[N],sz[N];
int find(int x){
  return f[x]==x?x:(f[x]=find(f[x]));
}
vector<int>ans[N];
int res=0;
void merge(int x,int y){
  int dx=find(x),dy=find(y);
  if(dx==dy)
    return;
  ans[x].pb(y);
  res+=sz[dy];
  sz[dx]+=sz[dy];
  f[dy]=dx;
}
int t,n,m,d[N],F[N],vis[N];
vector<int>v[N];
int main() {
  for(scanf("%d",&t);t;t--){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)d[i]=0,v[i].clear(),F[i]=i,
      sz[i]=1,f[i]=i,vis[i]=0,ans[i].clear();
    for(int i=1;i<=m;i++){
      int s,t;
      scanf("%d%d",&s,&t);
      v[s].pb(t);
      v[t].pb(s);
      d[s]++;
      d[t]++;
    }
    sort(F+1,F+1+n,[](int x,int y){
      return d[x]<d[y];
    });
    int ok=1;
    for(int i=1;i<=n;i++){
      res=0;
      for(auto k:v[F[i]]){
        if(vis[k]){
          merge(F[i],k);
        }else res++;
      }
      if(v[F[i]].size()<res)ok=0;
      vis[F[i]]=1;
    }
    if(!ok){
      cout<<"No\n";
      continue;
    }
    cout<<"Yes\n";
    for(int i=1;i<=n;i++){
      cout<<F[i]<<' '<<ans[F[i]].size();
      for(int j=0;j<ans[F[i]].size();j++){
        cout<<' '<<ans[F[i]][j];
      }
      cout<<"\n";
    }
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值