• Gym 101334C 无向仙人掌


    给出图,求他的“仙人掌度”,即求包括他自身的生成子图有多少?

    只能删去仙人掌上的叶子的一条边,然后根据乘法原理相乘;

    1、怎么求一个仙人掌叶子上有多少边? 可以利用点,边双连通的时间戳这个概念,但是绝对时间是不对的,只能用相对的时间戳。

    2、怎么把第二种情况剔除掉?    就是记录每一个点加入环中的次数;

    3、第三种情况,就是判连通了;

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int maxn = 20000 + 5;
      6 
      7 struct Sol {
      8     vector<int> G[maxn];
      9     int cyclecnt;
     10     int cycle[maxn];
     11     int dfn[maxn];
     12     int c[maxn];
     13     int n;
     14     int num[maxn];
     15 
     16     void init(int n) {
     17         this->n = n;
     18         for(int i=0; i<=n; i++)
     19             G[i].clear();
     20         memset(dfn,0,sizeof(dfn));
     21         memset(cycle,0,sizeof(cycle));
     22         memset(num,0,sizeof(num));
     23         cyclecnt = 0;
     24         dfn[1] = 1;
     25     }
     26 
     27     void AddEdge (int from,int to) {
     28         G[from].push_back(to);
     29         G[to].push_back(from);
     30     }
     31 
     32     void dfs(int u,int fa) {
     33         for(int i=0; i<G[u].size(); i++) {
     34             int v = G[u][i];
     35             if(v==fa) continue;
     36 
     37             if(!dfn[v]) {
     38                 dfn[v] = dfn[u] + 1;
     39                 dfs(v,u);
     40                 c[u]+=c[v];
     41             } else if(dfn[v]<dfn[u]) {
     42                 cycle[cyclecnt++] = dfn[u] - dfn[v] + 2;
     43                 c[u]++;
     44                 c[v]--;
     45             }
     46         }
     47     }
     48 
     49     void ans() {
     50         for(int i=1; i<=n; i++)
     51             if(c[i]>1||dfn[i]==0) {
     52                 puts("0");
     53                 return;
     54             }
     55         //int res = 1;
     56         //for(int i=0;i<cyclecnt;i++)
     57         //    res = res * cycle[i];
     58         //return res;
     59 
     60         int len = 0;
     61         num[0] = 1;
     62 
     63         for(int i=0; i<cyclecnt; i++) {
     64 
     65             for(int j=0; j<=len; j++)
     66                 num[j] = num[j]*cycle[i];
     67 
     68             for(int j=0; j<=len; j++) {
     69                 num[j+1] += num[j]/10;
     70                 num[j] = num[j]%10;
     71             }
     72             while(num[len+1]) {
     73                 num[len+2]+=num[len+1]/10;
     74                 num[++len]%=10;
     75             }
     76         }
     77 
     78         for(int i=len; i>=0; i--)
     79             printf("%d",num[i]);
     80         puts("");
     81     }
     82 
     83 
     84 
     85 } sol;
     86 
     87 int main() {
     88     freopen("cactus.in","r",stdin);
     89     freopen("cactus.out","w",stdout);
     90     int n,m;
     91     scanf("%d%d",&n,&m);
     92 
     93     sol.init(n);
     94 
     95     for(int i=0; i<m; i++) {
     96         int k,u;
     97         scanf("%d%d",&k,&u);
     98         for(int i=0; i<k-1; i++) {
     99             int v;
    100             scanf("%d",&v);
    101             sol.AddEdge(u,v);
    102             u = v;
    103         }
    104     }
    105 
    106     sol.dfs(1,-1);
    107 
    108     sol.ans();
    109 
    110     //printf("%d
    ",sol.ans());
    111 
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    格式控制符
    sort快速排序法
    堆积排序
    oracle常用命令
    C#中int和System.Int32理解总结
    IIS 7.5中的配置
    WPF循序渐进:XAML入门 .
    怎样找到excel两列之间同行相同的数据
    pl/sql functions and cbo costing
    Oracle 学习纲要
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6936595.html
Copyright © 2020-2023  润新知