[MemSQL Start[c]UP 3.0 - Round 1][Codeforces 859]E. Desk Disorder
题意:n个人和至多2n把椅子,每个人有现在正在坐的椅子和想要坐的椅子(可以相同)这两个椅子可选,一把椅子只能坐一个人,求方案数。
题解:将椅子看成点,人看成边,构成联通块只有两种可能:一种是\(E=V-1\),即一棵树的情况;一种是\(E=V\),即基环外向树。其他的情况显然是无解的,而这道题肯定有解,所以只有这两种情况。另一种理解方法是,由于图联通,所以必有\(E>=V-1\);由于每个工程师至少能选择一把椅子,所以有\(E<=V\)。
\(E=V-1\)时,该联通块为一棵树,方案数为V,因为树上只有一个点不会被选到,对每个没有选到的点方案唯一;\(E=V\)时,联通块上有环,环上的人只能选择全部坐在原位或者全部坐在想要坐的椅子上,方案数为2,环外的边方案唯一。一种特殊情况是一个人想要坐在自己正在坐的椅子上,此时方案数为1。
具体实现就用并查集瞎搞搞就出来了。
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int mo=1e9+7;
int head[maxn],nxt[maxn<<1],E[maxn<<1],Ecnt;
int n;
int ans;
void Add_Edge(int x,int y) {nxt[++Ecnt]=head[x];head[x]=Ecnt;E[Ecnt]=y;}
int fa[maxn<<1];
int sz[maxn];
int v[maxn<<1];
int Find(int x) {return x==fa[x]?x:fa[x]=Find(fa[x]);}
void Union(int x,int y)
{
int fx=Find(x),fy=Find(y);
sz[fy]+=sz[fx];
fa[fx]=fy;
}
int main()
{
scanf("%d",&n);
ans=1;
for (int i=1,x,y;i<=n;i++)
{
scanf("%d%d",&x,&y);
Add_Edge(x,y);
fa[x]=x;
fa[y]=y;
sz[x]=sz[y]=1;
}
for (int x=1;x<=n*2;x++) if (sz[x])
{
for (int j=head[x];j;j=nxt[j])
{
int y=E[j];
if (Find(x)==Find(y)) v[Find(y)]=max(v[Find(y)],1);
if (x==y) v[Find(y)]=2;
Union(x,y);
}
}
for (int x=1;x<=2*n;x++) if (Find(x)==x)
{
if (v[x]==1) ans=ans*2%mo;
if (v[x]==0) ans=(long long)ans*sz[x]%mo;
}
printf("%d\n",ans);
return 0;
}
2022年9月03日 14:16
Haryana Board Model Paper 2023 Class 1 Pdf Download with Answers for English Medium, Hindi Medium, Urdu Medium & Students for Small Answers, Long Answer, Very Long Answer Questions, and Essay Type Questions to Term1 & Term2 Exams at official website. HBSE Model Paper Class 1 New Exam Scheme or Question Pattern for Sammittive Assignment Exams (SA1 & SA2): Very Long Answer (VLA), Long Answer (LA), Small Answer (SA), Very Small Answer (VSA), Single Answer, Multiple Choice and etc.