uva 10253 Series-Parallel Networks 树的性质,可重排列
2015-09-16 16:27
405 查看
题目:https://uva.onlinejudge.org/external/102/10253.pdf
对于一棵树,每个结点下的子树位置互换 ,还是同一棵树
可以利用这一性质解决 串并联问题,
如果是并联,那么把结点标为并联
,每个子树都是并联中的一条路线,(并联不考虑位置,正满足树的性质)
有的子树会是一个叶子结点,表示该路线上只有一条边
还有的子树,不止一条边,那么这条路线可以是串联(总的来说如此,不能是并联 ),(因为如果是并联本身就可以合并到父节点上)。
下面串联同方法,那么把结点标为串联,
每个结点表示串连中的一部分,(因为题目要求,串联互换位置属于用一种方法,所以树的结构满足这个条件)
对于一棵树,每个结点下的子树位置互换 ,还是同一棵树
可以利用这一性质解决 串并联问题,
如果是并联,那么把结点标为并联
,每个子树都是并联中的一条路线,(并联不考虑位置,正满足树的性质)
有的子树会是一个叶子结点,表示该路线上只有一条边
还有的子树,不止一条边,那么这条路线可以是串联(总的来说如此,不能是并联 ),(因为如果是并联本身就可以合并到父节点上)。
下面串联同方法,那么把结点标为串联,
每个结点表示串连中的一部分,(因为题目要求,串联互换位置属于用一种方法,所以树的结构满足这个条件)
int n; ll dp[35]; int up[35]; int num[35]; ll dpans; ll C(ll la,ll sm) //一开始这里两个参数都是int ,没有考虑到传入的dp[]可以使long long { ll ans=1; for(int i=1;i<=sm;i++) { ans=ans* ( la-i+1)/i; } return ans; } void dfs(int step,int ed,int sum) { if(step==0) { int cnt=0; for(int i=1;i<n;i++) { cnt+=num[i]; } if(sum!=n||cnt<=1 ) return; ll ans=1; for(int i=1;i<n;i++) { if(!num[i]) continue; ans*= C(dp[i]+num[i]-1,num[i] ); } dpans+=ans; return; } if(sum>n) return ; for(int i=up[step];i>=0;i--) { num[step]=i; dfs(step-1,ed,sum+ step*i); } } void DP(int x) //搜索,把x 分成几类,比如 4=1+1+1+1 =1+1+2=2+2=1+3 !=4(因为不能分成只有1个叶子的子树) { n=x; for(int i=1;i<x;i++) { up[i]=x/i; } dpans=0; dfs(n-1,x,0); dp[x]=dpans; } int main() { dp[1]=1; //样例里dp[1]规定为1 for(int i=2;i<=30;i++) { DP(i); //一开始的dp[x] 意义是 有x个叶子(也就是x条边)的一个子树的方法数。 } for(int i=2;i<=30;i++) dp[i]*=2; //把并联节点换成串联,串联换成并联。 while(~scanf("%d",&n)&&n) { printf("%lld\n",dp ); } return 0; }
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<climits> #include<queue> #include<vector> #include<map> #include<sstream> #include<set> #include<stack> #include<utility> #pragma comment(linker, "/STACK:102400000,102400000") #define PI 3.1415926535897932384626 #define eps 1e-10 #define sqr(x) ((x)*(x)) #define FOR0(i,n) for(int i=0 ;i<(n) ;i++) #define FOR1(i,n) for(int i=1 ;i<=(n) ;i++) #define FORD(i,n) for(int i=(n) ;i>=0 ;i--) #define lson num<<1,le,mid #define rson num<<1|1,mid+1,ri #define MID int mid=(le+ri)>>1 #define zero(x)((x>0? x:-x)<1e-15) #define mk make_pair #define _f first #define _s second using namespace std; //const int INF= ; typedef long long ll; //const ll inf =1000000000000000;//1e15; //ifstream fin("input.txt"); //ofstream fout("output.txt"); //fin.close(); //fout.close(); //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); const int INF =0x3f3f3f3f; //const int maxn= ; //const int maxm= ; //by yskysker123
相关文章推荐
- POP3、SMTP、IMAP和Exchange都是个什么玩意?
- 标准SQL
- TCP协议总结--停止等待协议,连续ARQ协议,滑动窗口协议
- 在网站测试中如何做好安全性测试
- 关于BaseAdapter和simpleAdapter
- CSS3Ps -Photoshop图层特效转CSS3代码
- 作为团队Boss,如何处理PM与RD之间的矛盾?
- R语言连接Mysql数据库的步骤及简单使用mysql数据库中的数据
- iOS 延时的几种方法
- 桌面图标删除不了
- Wireshark抓取本机报文
- FilterInputStream的mark和resetf方法
- Monkey测试(二)
- 机器学习相关文章翻译目录-CSDN云计算专栏发布
- bootstrap_UI
- HDOJ 5442 Favorite Donut
- 格雷码的生成
- Swift学习笔记(三十三)——常量参数,变量参数和inout参数
- eclipse常用快捷键
- Flume学习6_flume配置文件