同桌与室友 计数类问题
题意:
题目描述:
班有 N 个人,从到编号。他们中有一些人住双人宿舍,一些人住单间,也
就是说一些人有唯一的一个室友,有些人则没有。同时有些人会和他的同桌共用一张双
人桌,另一些人则单独坐。
你需要求出有多少个排列,满足原本的人换到的宿舍以及桌子上后,原本
的室友以及同桌关系依旧不变,答案对取模。
输入格式
第一行三个整数,表示人数,双人宿舍数量,双人桌数量。
接下来行,每行两个整数,表示和同住一间双人宿舍。
接下来行,每行两个整数,表示和同用一张双人桌。
输出格式
输出一行一个整数,表示满足条件的排列数量。
样例 1 输入
7 2 2
1 2
3 4
1 4
5 6
样例 1 输出
4
样例 2 输入
5 2 1
1 2
3 4
1 4
2
样例 2 输出
2
数据范围与约定
对于%的数据,;
对于 % 的数据,;
对于额外% 的数据,一个人要么住单人间,要么就用单人桌;
对于额外 % 的数据, 保证 是偶数,
对于额外 % 的数据, 保证数据完全随机生成;
对于% 的数据,保证
一句话版:一张图有黑白两种边,求使得图同构的置换数
思路:
将双人宿舍关系看做是黑边,双人桌关系看做是白边,那么就是一个图同构的计数
考试时一看是图同构,打了个暴力就跑
其实这道题的图有特殊之处
每个点度数最多为2(白边黑边各一条)
因此每一个连通块要么是一个简单环,要么是一条链
分类计数即可。
具体来说,
如果有 个大小为 的环,那么这一部分答案为 ;
如果有 个长度相同,两段边同为黑或同为白的链,那么这一部分答案为 ;
如果有 个长度相同,两段边不同色的链,那么这一部分答案为 ;
注意事项:
做一道题最好能把题意极为简洁地概括出来,方便分析
牢牢抓住一道题的特殊点
code:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int p=1e9+7;
int n,m1,m2,rg,cnt,cl,ans=1;
int to[N][2],r[N],l[N][2];
bool vis[N];
inline int read()
{
int s=0,w=1; char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
return s*w;
}
void dfs(int u,int tp)
{
vis[u]=true;++cnt;
if(tp==-1)
{
if(to[u][0]&&!vis[to[u][0]]) dfs(to[u][0],0);
if(to[u][1]&&!vis[to[u][1]]) dfs(to[u][1],1);
return;
}
if(!to[u][tp^1]){rg=1;cl=tp;return;}
if(vis[to[u][tp^1]]) return;
dfs(to[u][tp^1],tp^1);
}
int main()
{
n=read(),m1=read(),m2=read();
for(int i=1;i<=m1;++i)
{
int x=read(),y=read();
to[x][0]=y,to[y][0]=x;
}
for(int i=1;i<=m2;++i)
{
int x=read(),y=read();
to[x][1]=y,to[y][1]=x;
}
for(int i=1;i<=n;++i)
{
if(vis[i]) continue;
rg=0;cnt=0;dfs(i,-1);
if(!rg)
{
ans=1ll*ans*cnt%p;
++r[cnt];
ans=1ll*ans*r[cnt]%p;
}
else
{
if(cnt&1)
{
++l[cnt][0];
ans=1ll*ans*l[cnt][0]%p;
}
else
{
ans=ans*2ll%p;
++l[cnt][cl];
ans=1ll*ans*l[cnt][cl]%p;
}
}
}
printf("%d\n",ans);
return 0;
}
NO PAIN NO GAIN
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现