四校聯考 獨立集

題目有點長,就貼過來好了。ios

計算一張給定的圖的最大獨立集不是一件容易的事情。 它每每須要一個比較高的複雜度來實現。 所以, 咱們常常使用隨機的辦法來試圖求出獨立集:隨意一個點的排列, 按順序考察每一個點。 若是將當前的點歸入獨立集中不會引發衝突(即不存在某條邊的兩端均入選的狀況), 則將這個點加入獨立集中。 按照這種辦法獲得的獨立集可能不是點數最多的, 因此咱們常常將上面的操做重複進行屢次, 從中選取點數最多的一次。spa

如今考慮一棵n個點的樹。若是使用上述辦法來求它的獨立集, 而且只進行一次, 咱們所獲得的獨立集的指望點數是多少?code

輸入樹,n<=200,mod 1e9+7。blog

考慮這樣dp,記f[i][j][sta]爲i的子樹中第j時刻(0...sz[i])i的狀態爲sta的pair(方案數,點數總和),sta有三種:0父親最終在獨立集中、1父親最終不在獨立集中,本身當前不在獨立集中、2本身當前已經在獨立集中了。ip

子樹合併的時候sta有三種:0自己最終在獨立集中,1自己最終不在獨立集中,孩子們當前都不在獨立集中,2孩子已經有若干在獨立集中了。string

轉移本身腦補一下... it

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
int n,sz[SZ]; Edg
const int MOD=1e9+7;
typedef pair<ll,ll> fn;
fn operator * (fn a,fn b)
{return fn(a.fi*b.fi%MOD,(a.fi*b.se+a.se*b.fi)%MOD);}
fn operator + (fn a,fn b)
{return fn((a.fi+b.fi)%MOD,(a.se+b.se)%MOD);}
fn operator + (fn a,ll b)
{return fn(a.fi,(a.se+a.fi*b)%MOD);}
fn operator * (fn a,ll b)
{return fn(a.fi*b%MOD,a.se*b%MOD);}
ll C[2333][2333];
fn f[555][555][3],t[555][3],tmp[555][3],qzh[555][3],hzh[555][3];
void dfs(int x,int fa)
{
    for esb(x,e,b) if(b!=fa) dfs(b,x);
    int s=0; t[s][0]=t[s][1]=fn(1,0);
    t[s][2]=pii(0,0); sz[x]=0;
    for esb(x,e,b) if(b!=fa)
    {
        for(int i=0;i<=sz[x]+sz[b];++i)
            memset(tmp[i],0,sizeof tmp[0]);
        for(int i=0;i<=sz[x];++i)
            for(int j=0;j<=sz[b];++j)
            {
                ll s=C[i+j][i]*C[sz[x]+sz[b]-i-j][sz[x]-i]%MOD;
                tmp[i+j][0]=tmp[i+j][0]+t[i][0]*f[b][j][0]*s;
                tmp[i+j][1]=tmp[i+j][1]+t[i][1]*f[b][j][1]*s;
                tmp[i+j][2]=tmp[i+j][2]+t[i][1]*f[b][j][2]*s
                +t[i][2]*f[b][j][1]*s+t[i][2]*f[b][j][2]*s;
            }
        sz[x]+=sz[b];
        for(int i=0;i<=sz[x]+sz[b];++i)
            memcpy(t[i],tmp[i],sizeof tmp[0]);
    }
    ++sz[x]; memcpy(qzh[0],t[0],sizeof t[0]);
    for(int i=1;i<sz[x];++i)
        for(int r=0;r<3;++r)
            qzh[i][r]=qzh[i-1][r]+t[i][r];
    memset(hzh[sz[x]],0,sizeof hzh[0]);
    for(int i=sz[x]-1;i>=0;--i)
        for(int r=0;r<3;++r)
            hzh[i][r]=hzh[i+1][r]+t[i][r];
    for(int i=0;i<=sz[x];++i)
    {
        if(i)
            f[x][i][0]=f[x][i][1]=qzh[i-1][2],
            f[x][i][2]=qzh[i-1][0]+1;
        else f[x][i][0]=f[x][i][1]=f[x][i][2]=pii(0,0);
        f[x][i][0]=f[x][i][0]+hzh[i][1]+hzh[i][2];
        f[x][i][1]=f[x][i][1]+(hzh[i][0]+1)+hzh[i][2];
    }
}
int main()
{
    for(int i=0;i<2333;++i)
    {
        C[i][0]=1;
        for(int j=1;j<=i;++j)
            C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
    }
    int T; scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n); M=0;
        for(int i=1;i<=n;++i) fst[i]=0;
        for(int i=1;i<n;++i)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            adde(a,b);
        }
        dfs(1,0);
        ll ans=f[1][n][0].se+f[1][n][2].se;
        ans=(ans%MOD+MOD)%MOD;
        printf("%d\n",int(ans));
    }
}
相關文章
相關標籤/搜索