题目: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[n]);
}
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