HDU 5729 Rigid Frameworks (联通块计数问题)

题目传送门

通过看题解画图可以发现:

不论怎么转,一列里的横边/一行里的竖边始终平行

当我们加固一个格子时,会让它所在的这一行的竖边和这一列的横边保证垂直

而我们的目标是求所有竖边和横边都保证垂直的方案数

把一行里的所有竖边看成一个点,把一列里的所有横边看成一个点。一共$n+m$个点

把图看成二分图,左侧$n$个点,右侧$m$个点。加固一个格子相当于在左侧的一个点和右侧的一个点之间连边!

我们的问题变成了求解二分图的连通图个数!

接下来就是很套路的$DP$了

定义$f(a,b)$表示左边$a$个点,右边$b$个点的连通二分图个数

对于连通图问题,我们依然采用常规的“固定思想”,我们固定左侧第一个点

直接求联通很困难,考虑用不合法的情况相减,可得$DP$方程:

$f(a,b)=3^{ab}-\sum_{i=0}^{a}\sum_{j=0}^{b}f(i,j)C_{a-1}^{i-1}C_{b}^{j}3^{(a-i)(b-j)}$

(注意i=a,j=b是不能转移的)

初值怎么赋需要思考

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define N1 65
 5 #define M1 3605
 6 #define ll long long
 7 using namespace std;
 8 const ll p=1000000007;
 9
10 int n,m,T;
11 int pw3[M1],C[N1][N1],f[N1][N1];
12
13 int main()
14 {
15     int i,j,a,b; n=60; m=60;
16     for(i=1,pw3[0]=1;i<=n*m;i++) pw3[i]=3ll*pw3[i-1]%p;
17     C[0][0]=1;
18     for(i=1;i<=max(n,m);i++)
19     {
20         C[i][0]=C[i][i]=1;
21         for(j=1;j<i;j++)
22             C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
23     }
24     f[1][0]=1; f[1][1]=2; //pw3[0]=0;
25     for(a=1,b=2;b<=m;b++)
26     {
27         f[a][b]=pw3[a*b];
28         for(j=0,i=1;j<b;j++)
29         {
30             f[a][b]=(f[a][b]-1ll*f[i][j]*C[a-1][i-1]%p*C[b][j]%p*pw3[(a-i)*(b-j)]%p+p)%p;
31         }
32     }
33     for(a=2;a<=n;a++)
34     {
35         for(b=1;b<=m;b++)
36         {
37             f[a][b]=pw3[a*b];
38             for(i=1;i<a;i++)
39             for(j=0;j<=b;j++)
40                 f[a][b]=(f[a][b]-1ll*f[i][j]*C[a-1][i-1]%p*C[b][j]%p*pw3[(a-i)*(b-j)]%p+p)%p;
41             for(j=0,i=a;j<b;j++)
42                 f[a][b]=(f[a][b]-1ll*f[i][j]*C[a-1][i-1]%p*C[b][j]%p*pw3[(a-i)*(b-j)]%p+p)%p;
43         }
44     }
45     while(scanf("%d%d",&n,&m)!=EOF)
46     {
47         printf("%d\n",f[n][m]);
48     }
49     return 0;
50 }

原文地址:https://www.cnblogs.com/guapisolo/p/10566844.html

时间: 2024-08-08 16:41:41

HDU 5729 Rigid Frameworks (联通块计数问题)的相关文章

HDU 5729 Rigid Frameworks(连通性DP)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5729 [题目大意] 给出一个n*m的方格框,可以在单位矩形中添加两种对角线的线,使得其变得稳定,问使得其变成稳定图形的方案数. [题解] 稳定状态指的是在n*m范围内每行每列都有一个固定的格子,并且联动,计算合法的情况非常的复杂,难以枚举,因此我们可以枚举非法情况,从组合数中减去即可.非法情况即将图形划分为合法部分和非法部分,注意枚举全面. [代码] #include <cstdio> usi

HDU 5729 Rigid Frameworks

目前还是不能彻底理解这题......http://blog.csdn.net/dpppbr/article/details/51972196 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #inc

HDU 4738 Caocao&#39;s Bridges ——(找桥,求联通块)

题意:给你一个无向图,给你一个炸弹去炸掉一条边,使得整个图不再联通,你需要派人去安置炸弹,且派去的人至少要比这条边上的人多.问至少要派去多少个,如果没法完成,就输出-1. 分析:如果这个图是已经是多个联通块了,那么一个人都不用去,如果不是,那么只要找出这个无向图上的桥并且哨兵数量最少的那座把它炸了就行(输出这条边上的哨兵数量即可).直接tarjan就可以写. 注意点:1.可能有重边,所以用手写邻接表的方式存图:2.如果一座桥上没有哨兵,那么你也得至少派去一个人去安置炸弹(因为炸弹不会自己飞过去啊

HDU 2952 Counting Sheep (DFS找联通块)

题目链接:请戳这里.   题目大意及思路:读懂题意就好了,就是DFS找联通块. 没什么好说的,见代码吧. #include<cstdio> #include<cstring> #include<algorithm> #define N 100+5 using namespace std; int n,m; char g[N][N]; int dir[4][2]={1,0,0,1,-1,0,0,-1}; void dfs(int x,int y) { for(int i=

Codeforces 731C. Socks 联通块

C. Socks time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input output: standard output Arseniy is already grown-up and independent. His mother decided to leave him alone for m days and left on a vacation. She have

C. Learning Languages 求联通块的个数

C. Learning Languages 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <queue&

Educational Codeforces Round 5 - C. The Labyrinth (dfs联通块操作)

题目链接:http://codeforces.com/contest/616/problem/C 题意就是 给你一个n行m列的图,让你求’*‘这个元素上下左右相连的连续的’.‘有多少(本身也算一个),每个’*‘的结果取模10.要是为’*‘输出结果,否则输出’.‘. 这个题目就是让你求连续的'.'联通块元素个数,求完一个联通块就把这个联通块标个记号(我设了ok[][]二维数组 表示这个位置的元素的联通块的标号,相连的则为同一个标号),之后这个联通块的每个元素的ans都为f(f为联通块元素个数),然

【UVA10765】Doves and bombs (BCC求割点后联通块数量)

题目: 题意: 给了一个联通无向图,现在问去掉某个点,会让图变成几个联通块? 输出的按分出的从多到小,若相等,输出标号从小到大.输出M个. 分析: BCC求割点后联通块数量,Tarjan算法. 联通块的数目在找到一个low[y]>=dfn[x]时累加,最后加一即可. 代码如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #inclu

Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量

D. Directed Roads ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it consists of n towns numbered from 1to n. There are n directed roads in the Udayland. i-th of them goes from town i to some other town