第七届蓝桥杯决赛 生成树计数 最后一题
2017-05-24 23:29
260 查看
第七届蓝桥杯决赛 生成树计数 最后一题 【此方法只能拿部分的分数】
生成树计数
给定一个 n*m 的格点图,包含 n 行 m 列共 n*m 个顶点,相邻的顶点之间有一条边。
【图1.png】给出了一个3*4的格点图的例子。
如果在图中删除部分顶点和其相邻的边,如上图删除第2行第3列和第3行第1列的顶点后,如【图2.png】所示。
图的生成树指包含图中的所有顶点和其中的一部分边,使得任意两个顶点之间都有由边构成的唯一路径。如果两个生成树包含有不同的边即被认为不同,则上图中共有31种不同的生成树,其中a边不选有10种,a边选有21种。
给出格点图中保留的顶点的信息,请计算该图一共有多少种不同的生成树。
【输入格式】
输入的第一行包含两个整数n, m,用空格分隔,表示格点图的行数和列数。
接下来n行,每行m个字母(中间没有分隔字符),每个字母必然是大写E或大写N,E表示对应的顶点存在,N表示对应的顶点不存在。保证存在至少一个顶点。
【输出格式】
输出一行,包含一个整数,表示生成树的个数。答案可能很大,你只需要计算答案除以1000000007的余数即可。
【样例输入】
3 4
EEEE
EENE
NEEE
【样例输出】
31
【数据规模与约定】
对于10%的数据,1<=n<=2。
对于30%的数据,1<=n<=3。
对于40%的数据,1<=n<=4。
对于50%的数据,1<=n<=5。
另有20%的数据,1<=n*m<=12。
另有10%的数据,1<=m<=15。
对于100%的数据,1<=n<=6,1<=m<=100000。
生成树计数
给定一个 n*m 的格点图,包含 n 行 m 列共 n*m 个顶点,相邻的顶点之间有一条边。
【图1.png】给出了一个3*4的格点图的例子。
如果在图中删除部分顶点和其相邻的边,如上图删除第2行第3列和第3行第1列的顶点后,如【图2.png】所示。
图的生成树指包含图中的所有顶点和其中的一部分边,使得任意两个顶点之间都有由边构成的唯一路径。如果两个生成树包含有不同的边即被认为不同,则上图中共有31种不同的生成树,其中a边不选有10种,a边选有21种。
给出格点图中保留的顶点的信息,请计算该图一共有多少种不同的生成树。
【输入格式】
输入的第一行包含两个整数n, m,用空格分隔,表示格点图的行数和列数。
接下来n行,每行m个字母(中间没有分隔字符),每个字母必然是大写E或大写N,E表示对应的顶点存在,N表示对应的顶点不存在。保证存在至少一个顶点。
【输出格式】
输出一行,包含一个整数,表示生成树的个数。答案可能很大,你只需要计算答案除以1000000007的余数即可。
【样例输入】
3 4
EEEE
EENE
NEEE
【样例输出】
31
【数据规模与约定】
对于10%的数据,1<=n<=2。
对于30%的数据,1<=n<=3。
对于40%的数据,1<=n<=4。
对于50%的数据,1<=n<=5。
另有20%的数据,1<=n*m<=12。
另有10%的数据,1<=m<=15。
对于100%的数据,1<=n<=6,1<=m<=100000。
#include <stdio.h> #include <bits/stdc++.h> #define mod 1000000007 typedef long long ll; using namespace std; int n,m,cnt,ans,kk; char s[8][100005]; int vis[700000]; int flag[700000]; int fi[700000]; class E{ public : int u,v; }; E e[1400000]; int find(int x){return fi[x]==x?x:fi[x]=find(fi[x]);} void dfs(int x,int sum,int bian){ //sum表示已经选择的点 bian表示已经选择的边 if(x==cnt){ if(sum==n*m-kk && bian==n*m-1-kk){ for(int i=0;i<=n*m;i++) fi[i]=i; for(int i=0;i<cnt;i++){ if(flag[i]==1){ int a=find(e[i].u); int b=find(e[i].v); if(a==b) return ; fi[a]=b; } } ans++; } return ; } int u=e[x].u,v=e[x].v; int k1=vis[u],k2=vis[v]; vis[u]=1;vis[v]=1;flag[x]=1; //选择x这条边 dfs(x+1,sum+2-k1-k2,bian+1); vis[u]=k1;vis[v]=k2;flag[x]=0; dfs(x+1,sum,bian); //不选择x这条边 } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>s[i]; for(int i=1;i<=n;i++){ for(int j=0;j<m;j++){ if(s[i][j]=='E' && s[i+1][j]=='E'){ e[cnt].u=(i-1)*m+j+1; e[cnt++].v=i*m+j+1; } if(s[i][j]=='E' && s[i][j+1]=='E'){ e[cnt].u=(i-1)*m+j+1; e[cnt++].v=(i-1)*m+j+2; } if(s[i][j]=='N') kk++; } } dfs(0,0,0); cout<<ans; return 0; }
相关文章推荐
- 第七届蓝桥杯决赛JavaA组第六题_生成树计数
- 第七届蓝桥杯大赛个人赛决赛(软件类C语言B组)第二题:凑平方数(深搜)
- 蓝桥杯 第七届决赛 平方末尾 JAVA
- 【第七届蓝桥杯大赛个人赛(软件类)决赛B组 一步之遥】
- 2015第七届蓝桥杯决赛C语言A组--穿越雷区(DFS)
- 第七届蓝桥杯决赛 棋子换位
- 【第七届蓝桥杯大赛个人赛(软件类)决赛B组】
- 第七届蓝桥杯决赛JavaA组第四题_机器人塔
- 第七届蓝桥杯决赛JavaA组第三题_棋子换位
- 蓝桥杯java第七届决赛第一题--愤怒小鸟
- 2016第七届蓝桥杯决赛心得
- 蓝桥杯第七届决赛JAVA真题----广场舞
- 第七届蓝桥杯决赛JavaA组第一题_阶乘位数
- 算法笔记_211:第七届蓝桥杯软件类决赛部分真题(Java语言A组)
- 算法笔记_212:第七届蓝桥杯软件类决赛真题(Java语言B组)
- 蓝桥杯java第七届决赛第二题--反幻方
- 2015蓝桥杯决赛 02 生成回文数(java)
- 2016年第七届蓝桥杯决赛心得
- 蓝桥杯--第七届决赛:圆圈舞
- 蓝桥杯第七届决赛JAVA真题----路径之谜