Connecting Vertices CodeForces - 888F (图论,计数,区间dp)

链接

大意: 给定邻接表表示两点是否可以连接, 要求将图连成树, 且边不相交的方案数

 

n范围比较小, 可以直接区间dp

$f[l][r]$表示答案, $g[l][r]$表示区间[l,r]全部连通且l,r间连边的方案

#include <iostream>
#include <algorithm>
#include <cstdio>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)

using namespace std;
typedef long long ll;
const int P = 1e9+7, N = 555;
struct _ {int f=-1,g;}dp[N][N];
int a[N][N], n;

_ dfs(int l, int r) {
	_ &ans = dp[l][r];
	if (~ans.f) return ans;
	ans.f=0;
	for (int x=l; ; x=(x+1)%n) {
		if (x!=l) (ans.f+=(ll)dfs(l,x).g*dfs(x,r).f%P)%=P;
		if (x==r) break;
		if (a[l][r]) (ans.g+=(ll)dfs(l,x).f*dfs((x+1)%n,r).f%P)%=P;
	}
	return ans;
}

int main() {
	scanf("%d", &n);
	REP(i,0,n-1)REP(j,0,n-1) scanf("%d", &a[i][j]),dp[i][i].f=1;
	printf("%d\n", dfs(0,n-1).f);
}

 

转载于:https://www.cnblogs.com/uid001/p/10415928.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值