自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
标签:
自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
一个整数,表示不同的满足要求的树的个数,无解输出0
两棵树分别为1-2-3;1-3-2
题解:天哪。。这要是在考场上怎么想得完,蒟蒻做不到。。。
用到了prufer数列,以下摘自度娘:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(‘ ‘) 8 #define ENT putchar(‘\n‘) 9 using namespace std; 10 const int maxn=1000+10,maxm=10000+10,inf=-1u>>1; 11 const int MAXN=3010; 12 struct bign{ 13 int len,s[MAXN]; 14 bign(){memset(s,0,sizeof(s));len=1;} 15 bign(int num){*this=num;} 16 bign(const char *num){*this=num;} 17 bign operator = (const int num){ 18 char s[MAXN]; sprintf(s,"%d",num); 19 *this = s;return *this; 20 } 21 bign operator = (const char *num){ 22 for(int i=0;num[i]==‘0‘;num++); 23 len=strlen(num); 24 for(int i=0;i<len;i++) s[i]=num[len-i-1]-‘0‘; 25 return *this; 26 } 27 bign operator + (const bign &b) const{ 28 bign c;c.len=0; 29 for(int i=0,g=0;g||i<max(len,b.len);i++) { 30 int x=g; 31 if(i<len) x+=s[i]; 32 if(i<b.len) x+=b.s[i]; 33 c.s[c.len++]=x%10; 34 g=x/10; 35 } return c; 36 } 37 void clean(){while(len > 1 && !s[len-1]) len--;return;} 38 bign operator * (const bign &b){ 39 bign c; 40 c.len=len+b.len; 41 for(int i=0;i<len;i++) for(int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j]; 42 for(int i=0;i<c.len;i++){ 43 c.s[i+1]+=c.s[i]/10; 44 c.s[i]%=10; 45 } c.clean();return c; 46 } 47 bign operator - (const bign &b){ 48 bign c;c.len=0; 49 for(int i=0,g=0;i<len;i++){ 50 int x=s[i]-g;if(i<b.len) x-=b.s[i]; 51 if(x>=0) g=0; 52 else g=1,x+=10; 53 c.s[c.len++]=x; 54 } c.clean();return c; 55 } 56 bool operator < (const bign &b) { 57 if(len!=b.len) return len<b.len; 58 for(int i=len-1;i>=0;i--){ 59 if(s[i]!=b.s[i]) return s[i]<b.s[i]; 60 } return false; 61 } 62 bool operator > (const bign &b){ 63 if(len!=b.len) return len>b.len; 64 for(int i=len-1;i>=0;i--){ 65 if(s[i]!=b.s[i]) return s[i]>b.s[i]; 66 } return false; 67 } 68 bool operator == (const bign &b){ 69 return !(*this>b)&&!(*this<b); 70 } 71 void print(){ 72 for(int i=len-1;i>=0;i--) putchar(s[i]+‘0‘);return; 73 } 74 }ans; 75 bign pow(int x0,int y){ 76 bign x=x0,ans=1;for(int i=y;i;i>>=1,x=x*x)if(i&1)ans=ans*x;return ans; 77 } 78 int n,m,tot=0,fenmu[maxn],fenzi[maxn];bool prime[maxn]; 79 void initp(){ 80 memset(prime,true,sizeof(prime));prime[0]=prime[1]=false;prime[2]=true; 81 for(int i=2;i*i<=n;i++)if(prime[i])for(int j=i*i;j<=n;j+=i)prime[j]=false; 82 } 83 void split(int t,int a[]){ 84 int sum;for(int i=2;i<=t;i++)if(prime[i]){ 85 sum=i;while(sum<=t)a[i]+=t/sum,sum*=i; 86 }return; 87 } 88 inline int read(){ 89 int x=0,sig=1;char ch=getchar(); 90 while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();} 91 while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar(); 92 return x*=sig; 93 } 94 inline void write(int x){ 95 if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x; 96 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 97 for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return; 98 } 99 void init(){ 100 n=read();initp();int d; 101 for(int i=1;i<=n;i++){ 102 d=read(); 103 if(d<0){m++;continue;} 104 if(d>1)split(d-1,fenmu); 105 tot+=d-1; 106 }split(n-2-tot,fenmu);split(n-2,fenzi); 107 return; 108 } 109 void work(){ 110 for(int i=1;i<=1000;i++)fenzi[i]-=fenmu[i];ans=1; 111 for(int i=1;i<=1000;i++)if(fenzi[i])ans=ans*pow(i,fenzi[i]); 112 if(m)ans=ans*pow(m,n-2-tot); 113 if(tot>n-2||(tot<n-2&&!m)){write(0);return;} 114 return; 115 } 116 void print(){ 117 ans.print(); 118 return; 119 } 120 int main(){init();work();print();return 0;}
标签:
原文地址:http://www.cnblogs.com/chxer/p/4639448.html