洛谷 P4129 [SHOI2006]仙人掌

原创 2018年04月17日 15:54:26

题意:

给出一个无向图,在判断原图是否为一个仙人掌图的基础上,求仙人掌的支撑子图个数

支撑子图:去掉一些边,但并不改变连通性,这样得到的子图为支撑子图。

题解:

1个仙人掌 <=> 连通性&点双均为简单环。
于是先dfs一次检验连通性,然后tarjan求点双,检验点双的点数=边数。

Ans=(+1)

因为树边不可删除,每一个环上可以选择不删,也可以选择删除一条边,两条以上则破坏连通性。
需要使用高精度姿势,且标答数据错误。。。有前导0。。。但疼的一批。
Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e4+100;
const int maxm = 1e6+100;
int first[maxn],des[maxm*2],nxt[maxm*2],tot;
int m,n;
int dfn[maxn],low[maxn],dfs_clock;
bool vis[maxn];
int bcc_cnt,bcc_no[maxn];
int st[maxm],top;
struct Big_Number{
    LL a[1000],len;
    const LL bas = 100000000;
    void init(){
        len=1;
        memset(a,0,sizeof a);
        a[0]=1;
    }
    void mul(LL val){
        for (int i=0;i<len;i++){
            a[i] = a[i]*val;
        }
        for (int i=0;i<len;i++){
            a[i+1] += a[i]/bas;
            a[i]%=bas;
        }
        while (a[len]){
            a[len+1] = a[len]/bas;
            a[len]%=bas;
            len++;
        }
    }
    void print(){
        printf("%lld",a[len-1]);
        for (int i=len-2;i>=0;i--){
            printf("%.8lld",a[i]);
        }
        printf("\n");
    }
}ans;
inline void addEdge(int x,int y){
    tot++;
    des[tot] =y;
    nxt[tot] = first[x];
    first[x] = tot;
}
void input(){
    scanf("%d%d",&n,&m);
    for (int i=0;i<m;i++){
        int u,k;
        scanf("%d%d",&k,&u);
        for (int j=1;j<k;j++){
            int v;
            scanf("%d",&v);
            addEdge(u,v);
            addEdge(v,u);
            u =v;
        }
    }
}
void dfs(int u){
    vis[u] =1;
    for (int t = first[u];t;t=nxt[t]){
        int v = des[t];
        if (vis[v])continue;
        dfs(v);
    }
}
bool dfs(int node,int fa,int Eid){
 //   cout<<"dfs: "<<node<<" "<<fa<<" "<<endl;
    dfn[node] = low[node] = ++dfs_clock;
    st[top++] = Eid;
    for (int t = first[node];t;t=nxt[t]){
        int v = des[t];
        if (v==fa)continue;
        if (!dfn[v]){
            if (!dfs(v,node,t))return false;
            low[node] = min(low[node],low[v]);
            if (low[v]==dfn[node]){
          //      cout<<"find bcc:"<<node<<" "<<v<<endl;
                bcc_cnt++;
                LL e_cnt=1;
                bool ok = true;
                while (true){
                    int tt = st[--top];
                    if (bcc_no[des[tt]]!=bcc_cnt){
                        bcc_no[des[tt]] = bcc_cnt;
                        e_cnt++;
                    }else{
                        ok =false;
                    }
                    if (tt==t)break;
                }
                if (ok){
                    ans.mul(e_cnt);
                }else{
                    return false;
                }
            }
        }else if (dfn[v]<dfn[node]){
            low[node] = min(low[node],dfn[v]);
            st[top++] = t;
        }
    }
    if (st[top-1]==Eid)top--;
    return true;
}
void solve(){
    dfs(1);
    for (int i=1;i<=n;i++){
        if (!vis[i]){
            cout<<0<<endl;
            return;
        }
    }
    ans.init();
    if (dfs(1,-1,-1)){
        ans.print();
    }else{
        cout<<0<<endl;
    }
}
int main(){
    #ifdef debug
    freopen("input.in","r",stdin);
    #endif // debug
    input();
    solve();
    return 0;
}
版权声明:本文为博主原创文章,转载的话评论区留个名就OK辣 https://blog.csdn.net/calabash_boy/article/details/79976081

1023: [SHOI2008]cactus仙人掌图

好难不会做TAT。 只好Orz各路神犇的题解。 搞了一个小时,终于乱搞出来了。 大概就是Tarjan+树形DP+环上单调队列DP+乱七八糟的讨论。 脑子有点糊了。 #include #inc...
  • nlj1999
  • nlj1999
  • 2015-12-23 09:56:21
  • 207

bzoj 1815: [Shoi2006]color 有色图 (置换+dfs)

1815: [Shoi2006]color 有色图 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 212  Solved: 102 [Submit][S...
  • clover_hxy
  • clover_hxy
  • 2017-03-09 19:27:15
  • 175

bzoj1478/1815[Shoi2006]color 有色图

置换-ploya 双倍经验喔
  • u010336344
  • u010336344
  • 2017-03-22 18:56:59
  • 554

仙人掌企业网站管理系统

  • 2009年12月08日 17:32
  • 3.18MB
  • 下载

ZJOI2017 仙人掌 转化模型后的简单树形dp

题目大意给定一个nn个点,mm条变的无向无自环的连通图,问都多少种加边方案使得加完边的图是一幅没有重边仙人掌。(即满足任意一条边只属于一个简单环中的无向无自环图的连通图) 多组数据。∑n≤5∗105...
  • YxuanwKeith
  • YxuanwKeith
  • 2017-03-26 10:14:23
  • 721

【Cactus仙人掌图】仙人掌基础知识学习笔记

首先膜一下vfk领先全球的动态仙人掌栽培技术… 然后谢谢Time-Machine学长在暑假集训时候讲了仙人掌DP. 然后感觉听得并不是很懂…所以再来对着论文学一遍顺便写一写例题代码 这一篇主要先...
  • CreationAugust
  • CreationAugust
  • 2015-08-27 08:43:43
  • 5445

BZOJ 1815: [Shoi2006]color 有色图

这题时限不知道怎么搞的,我的代码跑了4000+MS A掉了,可是时限是4S 然后做法什么的不是很懂,好像很玄学的样子,具体看08年的论文。 大概是利用划分对置换进行分类,每一类的循环节个数是一样的...
  • nlj1999
  • nlj1999
  • 2016-03-23 19:57:15
  • 999

ZJOI2017 仙人掌

题解如果一开始的图就不是仙人掌,答案显然为0,可以Tarjan判断。 环显然不能产生贡献,所以可以把环边都断开。 现在模型转化为,给定一棵树,用路径去覆盖树上的每一条边,且路径不能相交,求方案数。...
  • Akak__ii
  • Akak__ii
  • 2017-03-25 11:52:48
  • 862

仙人掌相关问题的处理方法(未完待续)

仙人掌相关问题的处理方法如图所示:仙人掌图就是长得像仙人掌的图嘛(我真没看出哪里像了)定义:对一个无向连通图,任意一条边属于至多一个简单环。 桥边:非环边,就是连接环的那些边; 环边:就是环中的边嘛。...
  • zhangche0526
  • zhangche0526
  • 2017-05-13 21:36:19
  • 1373

BZOJ 3899 仙人掌树的同构 仙人掌同构+KMP算法

题目大意:给定一棵仙人掌,求有多少自同构仙人掌同构问题= = 曾经出过一个判断两个仙人掌是否同构的题,感觉和这个题很类似首先假设这是一棵树,考虑怎么做我们首先找到树的重心(如果有两个就在中间加一个点...
  • PoPoQQQ
  • PoPoQQQ
  • 2015-07-10 14:01:14
  • 1723
收藏助手
不良信息举报
您举报文章:洛谷 P4129 [SHOI2006]仙人掌
举报原因:
原因补充:

(最多只允许输入30个字)