• POJ 1523 SPF 求割点的好(板子)题!


    题意:

    给个无向图,问有多少个割点,对于每个割点求删除这个点之后会产生多少新的点双联通分量


    题还是很果的

    怎么求割点请参考tarjan无向图

    关于能产生几个新的双联通分量,对于每个节点u来说,我们判断他是否是割点,即判断是否满足他的儿子v的low[v]>dfn[u]

    而这个时候割掉这个点就会让双联通分量增加,所以搞一个数组记录一下这个操作的次数就行

    请注意在是否是根节点的问题上特判

    !!注意输出格式!!

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define N 5010
     5 #define M 10100
     6 #define Max(a,b,c) max(max(a,b),c)
     7 using namespace std;
     8 int head[N],n,m,ecnt=2,u,v,dfn[N],low[N],indx,du[N],ans,isap[N],ap,task,sum[N];
     9 struct edge
    10 {
    11     int u,v,nxt;
    12 }e[M*2];
    13 void add(int u,int v)
    14 {
    15     e[ecnt].v=v;
    16     e[ecnt].nxt=head[u];
    17     e[ecnt].u=u;
    18     head[u]=ecnt++;
    19     e[ecnt].v=u;
    20     e[ecnt].nxt=head[v];
    21     e[ecnt].u=v;
    22     head[v]=ecnt++;
    23 }
    24 void dfs(int u,int fa)
    25 {
    26     dfn[u]=low[u]=++indx;
    27     int n_ch=0;
    28     for (int i=head[u];i;i=e[i].nxt)
    29     {
    30     int v=e[i].v;
    31     if (!dfn[v])
    32     {
    33         dfs(v,i);
    34         low[u]=min(low[u],low[v]);
    35         if (low[v]>=dfn[u])
    36         isap[u]=1,ap++,sum[u]++;
    37         n_ch++;
    38     }
    39     else
    40         if (v!=fa)
    41         low[u]=min(dfn[v],low[u]);
    42     }
    43     if (fa==-1 && n_ch==1)
    44     isap[u]=0,ap--;
    45     if (isap[u] && fa!=-1) sum[u]++;
    46 }
    47 void init()
    48 {
    49     n=0;
    50     memset(sum,0,sizeof(sum));
    51     memset(head,0,sizeof(head));
    52     memset(dfn,0,sizeof(dfn));
    53     memset(isap,0,sizeof(isap));
    54     ecnt=2;
    55     ans=0;
    56     indx=0;
    57     ap=0;
    58 }
    59 void solve()
    60 {
    61     if (n==0) return;
    62     task++;
    63         for (int i=1;i<=n;i++)
    64     if (!dfn[i]) dfs(i,-1);
    65     printf("Network #%d
    ",task);
    66     if (ap==0)
    67     printf("  No SPF nodes
    ");
    68     for (int i=1;i<=n;i++)
    69     if (isap[i])
    70         printf("  SPF node %d leaves %d subnets
    ",i,sum[i]);
    71     putchar('
    ');
    72     init();
    73 }
    74 int main()
    75 {
    76     //  freopen("1.in","r",stdin);
    77     while (1)
    78     {
    79     while (scanf("%d",&u)!=EOF)
    80     {
    81         if (u==0)
    82         {
    83         solve();
    84         continue;
    85         }
    86         if (scanf("%d",&v)==EOF) break;
    87         n=Max(n,u,v);
    88         add(u,v);
    89         //   printf("%d %d
    ",u,v);
    90     }
    91     if (n==0) break;
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    单调栈模板
    Yet Another Broken Keyboard[双指针]
    经典递归集合
    [未完成]ECRound 80
    #614 C. NEKO's Maze Game[简易DFS,0|1转换]
    等差数列异或和模板
    线段树基础题
    前缀和&差分
    优先队列
    st表模板
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7845943.html
Copyright © 2020-2023  润新知