链接
题意:
给出n个点m条无向边,让你构造出每个节点只有一个出度的图,问有多少种?
分析:
开始读错题了。读成每个节点可以有大于等于1的出度
我们知道正确题意之后,进行解读,要求每个节点只有一个出度得知,在一个连通图中边数一定只能有节点数这么多,这样就有两种选择,所以我们就将问题转化成找合法的连通图,所谓合法就是边与连通图中的节点相等,
我选择用并查集维护,并且维护边数点数。
/// 欲戴皇冠,必承其重。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef unsigned long long ull;
#define x first
#define y second
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define debug(x) cout << #x << ": " << x << endl;
const int MOD = 998244353;
const int mod = 998244353;
const int N = 5e5 + 10;
const int dx[] = {0, 1, -1, 0, 0, 0, 0};
const int dy[] = {0, 0, 0, 1, -1, 0, 0};
const int dz[] = {0, 0, 0, 0, 0, 1, -1};
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ll n, m,p;
ll a[N],b[N],c[N];
ll ans;
ll f(ll x){
if(a[x]==x) return x;
return a[x]=f(a[x]);
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++) a[i]=i,b[i]=1,c[i]=1;
for(int i=1;i<=m;i++){
ll x,y;
cin>>x>>y;
if(x>y) swap(x,y);
ll fx,fy;
fx=f(x);
fy=f(y);
if(fx==fy){
b[fx]++;
continue;
}else {
a[fx]=fy;
c[fy]+=c[fx];
b[fy]+=b[fx];
}
}
ll ans=1;
for(int i =1 ;i<=n;i++){
if(a[i]==i){
if(b[i]==c[i]+1){
ans=ans*2%mod;
}else {
puts("0");
return ;
}
}
}
cout<<ans<<endl;
}
int main()
{
ll t = 1;
///scanf("%lld", &t);
while(t--)
{
solve();
}
return 0;
}

这篇博客探讨了如何构造一种特殊的无向图,其中每个节点恰好有一个出度。通过并查集来维护图的连通性,作者分析了题目要求的条件,即边的数量必须等于节点数量,以确保每个节点只有一个出度。文章通过实例展示了如何使用并查集解决此问题,并给出了C++代码实现,最后输出合法构造的连通图的数量。

1433

被折叠的 条评论
为什么被折叠?



