挖坑..
---------------------------
一 生成子图
POJ 2793 Cactus含有G的所有顶点的子图称为G的生成子图。
问图是不是仙人掌树,若是仙人掌树,有多少生成子图。
对于仙人掌树上的一个环,只删去一条边,仍是原图的生成子图。
所以找到树上的每一个环,记录环上的点数,所有环上的点数相乘即是生成子图个数。
数据较大要用高精度处理。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define fil(x) memset(x,0,sizeof(x))
#define clr(x,a) memset(x,a,sizeof(x))
using namespace std;
const int maxn=42111;
const int maxm=1111111;
struct EdgeNode{
int to;
int cnt;
int next;
}edges[maxm];
int head[maxn],edge;
bool vis[maxn],inpath[maxn];
int n,m;
int top,totc;
int stack[maxn],stackE[maxn];
int len[maxn];
int d;
int ans[maxn];
void addedge(int u,int v){
edges[edge].cnt=0;
edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
}
void init(){
fil(inpath);
fil(vis);
clr(head,-1);
edge=0;
totc=0;
top=0;
}
bool input(){
if (~scanf("%d%d",&n,&m)){
init();
for (int i=0;i<m;i++){
int lst=-1,tot,u;
scanf("%d%d",&tot,&lst);
for (int j=1;j<tot;j++){
scanf("%d",&u);
addedge(lst,u);
addedge(u,lst);
lst=u;
}
}
return true;
}
return false;
}
bool dfs(int u,int from){
vis[u]=true;
inpath[u]=true;
stack[++top]=u;
stackE[top]=from;
for (int i=head[u];i!=-1;i=edges[i].next){
if ((i^1)==from) continue;
int v=edges[i].to;
if (!inpath[v]){
if (vis[v]) continue;
if (!dfs(v,i)) return false;
}
else{
len[totc]=2;
for (int k=top;stack[k]!=v;k--){
if (edges[stackE[k]].cnt) return false;
edges[stackE[k]].cnt++;
edges[stackE[k]^1].cnt++;
len[totc]++;
}
totc++;
if (edges[i].cnt) return false;
edges[i].cnt++;
edges[i^1].cnt++;
}
}
top--;
inpath[u]=false;
return true;
}
bool isCactus(){
if (!dfs(1,-1)){
printf("0\n");
return false;
}
for (int i=1;i<=n;i++){
if (!vis[i]){
printf("0\n");
return false;
}
}
return true;
}
void multi(int ans[],int x){
int tmp=0;
for (int i=0;i<d;i++){
ans[i]*=x;
ans[i]+=tmp;
tmp=ans[i]/10;
ans[i]%=10;
}
while (tmp){
ans[d++]=tmp%10;
tmp/=10;
}
}
void calculate(){
d=1;
ans[0]=1;
for (int i=0;i<totc;i++){
multi(ans,len[i]);
}
}
void output(){
for(int i=d-1;i>=0;i--) {
printf("%d",ans[i]);
}
printf("\n");
}
int main()
{
while (input()){
if (!isCactus()) continue;
calculate();
output();
}
return 0;
}
---------------------------
二 BCCDP
POJ 3567 Cactus Reloaded
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------