叉姐的魔法训练(第七课)---- 在沙漠中的长途旅行

挖坑..

---------------------------

一 生成子图

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

---------------------------

---------------------------

---------------------------

---------------------------

---------------------------

---------------------------

---------------------------

posted on 2013-10-03 20:44  电子幼体  阅读(178)  评论(0编辑  收藏  举报

导航