点仙人掌(cactus)

时间限制: 1 Sec 内存限制: 512 MB


题解
n k 3 nk^3 的暴力,在树上做树形 d p dp
C o d e Code:

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int mod=1e9+7,N=1e6+5;
int cnt,id,belong[N],n,m,top,K,ans,ti,head[N],dfn[N],low[N];
int stack[N],instack[N],S[10005][31],F[10005][31],A[N],B[35];
vector<int> vec[N];
struct node
{
	int vet,next;
}edge[N];
void add(int u,int v)
{
	edge[++cnt].vet=v;
	edge[cnt].next=head[u];
	head[u]=cnt;
}
void Tarjan(int x,int fa)
{
	dfn[x]=low[x]=++ti;
	stack[++top]=x;
	instack[x]=1;
	for(int i=head[x];i;i=edge[i].next)
	{
		int V=edge[i].vet;
		if(V==fa)continue;
		if(!dfn[V])
		{
			Tarjan(V,x);
			low[x]=min(low[x],low[V]);
		}else if(instack[V])
			low[x]=min(low[x],dfn[V]);
	}
	if(low[x]==dfn[x])
	{
		int u=-1;
		id++;
		while(u!=x)
		{
			u=stack[top--];
			vec[id].push_back(u);
			belong[u]=id;
			instack[u]=0;
		}
	}
}
void solve(int x,int fa,int ST)
{
	int st=0;
	for(int cas=0;cas<vec[x].size();cas++)
	{
		int now=vec[x][cas];
		if(now==ST)st=cas;
		S[now][1]=1;
		for(int i=head[now];i;i=edge[i].next)
		{
			int V=edge[i].vet;
			if(belong[V]==fa||belong[now]==belong[V])continue;
			solve(belong[V],x,V);
			for(int X=K;X>=1;X--)
				for(int Y=1;Y<X;Y++)
					(S[now][X]+=1ll*S[now][X-Y]*F[V][Y]%mod)%=mod;
		}
	}
	int len=(int)vec[x].size();
	for(int cas=0;cas<len;cas++)stack[cas]=vec[x][cas];
	int tag=0;
	for(int X=1;X<=K;X++)F[ST][X]=S[ST][X];
	for(int i=0;i<len;i++)
	{
		for(int j=1;j<=K;j++)A[j]=S[stack[i]][j],(ans+=A[j])%=mod;
		int FF=(i==st);
		int ss=1;
		for(int j=(i+1)%len;j!=i;j=(j+1)%len)
		{
			if((j+1)%len==i)
			{
				if(tag)break;
				tag=1;
			}
			if(j==st)FF=1;
			int now=stack[j];
			for(int X=1;X<=K;X++)B[X]=0;
			for(int X=K;X>=1;X--) 
				for(int Y=1;Y<X;Y++) 
					(B[X]+=1ll*A[X-Y]*S[now][Y]%mod)%=mod;
			for(int X=1;X<=K;X++)A[X]=B[X],(ans+=A[X])%=mod;
			int flag=0;
			for(int X=1;X<=K;X++)if(A[X])flag=1;
			if(!flag)break;
			if(FF)for(int X=1;X<=K;X++)(F[ST][X]+=A[X])%=mod;
			ss++;
			if(ss>K)break;
		}
	}
}
int main()
{
	scanf("%d%d%d",&n,&m,&K);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	Tarjan(1,0);
	solve(belong[1],0,1);
	printf("%d\n",ans);
	return 0;
}