叉姐的魔法训练(第七课)---- 在沙漠中的长途旅行
挖坑..
---------------------------
一 生成子图
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
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------