BZOJ 1093 [ZJOI2007]最大半连通子图

系统 1751 0

以前做过poj的一个判断图是否为弱连通的题,然后,这个题和poj那个差不多。

先强连通缩点,然后重新构图,然后找出包含点数最多的 ,统计个数即可,可以用拓扑排序搞~

 

pS:重新构图时有重边,然后导致统计方案数的重复。。wa了好久。。还是wzc神犇告诉我这个蒟蒻的。。

 

View Code
        
            1
        
         #include <iostream>


        
            2
        
         #include <cstdio>


        
            3
        
         #include <cstdlib>


        
            4
        
         #include <cstring>


        
            5
        
         #include <algorithm>


        
            6
        
        
            7
        
        
          #define
        
         N 200000


        
            8
        
        
          #define
        
         M 5000000


        
            9
        
        
          #define
        
         BUG system("pause")


        
           10
        
        
           11
        
        
          using
        
        
          namespace
        
        
           std;


        
        
           12
        
        
           13
        
        
          int
        
        
           head[N],to[M],next[M];


        
        
           14
        
        
          int
        
        
           dfn[N],low[N];


        
        
           15
        
        
          int
        
        
           st[M],ed[M];


        
        
           16
        
        
          int
        
        
           n,m,cnt,ans,ansnum,mod;


        
        
           17
        
        
          int
        
        
           divg,belong[N],t,p,stk[N],val[N];


        
        
           18
        
        
          bool
        
        
           fg[N];


        
        
           19
        
        
          int
        
         num[N],
        
          in
        
        
          [N],dp[N],q[M],vis[N];


        
        
           20
        
        
           21
        
         inline 
        
          void
        
         add(
        
          int
        
         u,
        
          int
        
        
           v)


        
        
           22
        
        
          {


        
        
           23
        
             to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++
        
          ;


        
        
           24
        
        
          }


        
        
           25
        
        
           26
        
         inline 
        
          void
        
        
           read()


        
        
           27
        
        
          {


        
        
           28
        
             memset(head,-
        
          1
        
        ,
        
          sizeof
        
         head); cnt=
        
          0
        
        
          ;


        
        
           29
        
             scanf(
        
          "
        
        
          %d%d%d
        
        
          "
        
        ,&n,&m,&
        
          mod);


        
        
           30
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=m;i++
        
          )


        
        
           31
        
        
              {


        
        
           32
        
                 scanf(
        
          "
        
        
          %d%d
        
        
          "
        
        ,&st[i],&
        
          ed[i]);


        
        
           33
        
        
                  add(st[i],ed[i]);


        
        
           34
        
        
              }


        
        
           35
        
        
          }


        
        
           36
        
        
           37
        
         inline 
        
          void
        
         dfs(
        
          int
        
        
           u)


        
        
           38
        
        
          {


        
        
           39
        
             low[u]=dfn[u]=++
        
          t;


        
        
           40
        
             stk[++p]=u; fg[u]=
        
          true
        
        
          ;


        
        
           41
        
        
          for
        
        (
        
          int
        
         i=head[u];~i;i=
        
          next[i])


        
        
           42
        
        
              {


        
        
           43
        
        
          if
        
        (!
        
          dfn[to[i]])


        
        
           44
        
        
                  {


        
        
           45
        
        
                      dfs(to[i]);


        
        
           46
        
                     low[u]=
        
          min(low[u],low[to[i]]);


        
        
           47
        
        
                  }


        
        
           48
        
        
          else
        
        
          if
        
        (fg[to[i]]) low[u]=
        
          min(low[u],dfn[to[i]]);


        
        
           49
        
        
              }


        
        
           50
        
        
          if
        
        (dfn[u]==
        
          low[u])


        
        
           51
        
        
              {


        
        
           52
        
                 divg++
        
          ;


        
        
           53
        
        
          int
        
         tmp=-
        
          1
        
        
          ;


        
        
           54
        
        
          while
        
        (tmp!=
        
          u)


        
        
           55
        
        
                  {


        
        
           56
        
                     tmp=stk[p--
        
          ];


        
        
           57
        
                     belong[tmp]=
        
          divg;


        
        
           58
        
                     val[divg]++
        
          ;


        
        
           59
        
                     fg[tmp]=
        
          false
        
        
          ;


        
        
           60
        
        
                  }


        
        
           61
        
        
              }


        
        
           62
        
        
          }


        
        
           63
        
        
           64
        
         inline 
        
          void
        
        
           topsort()


        
        
           65
        
        
          {


        
        
           66
        
        
          int
        
         h=
        
          1
        
        ,t=
        
          1
        
        
          ,u;


        
        
           67
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=divg;i++
        
          )


        
        
           68
        
        
          if
        
        (
        
          in
        
        [i]==
        
          0
        
        
          )


        
        
           69
        
        
                  {


        
        
           70
        
                     q[t++]=
        
          i;


        
        
           71
        
                     dp[i]=
        
          val[i];


        
        
           72
        
                     num[i]=
        
          1
        
        
          ;


        
        
           73
        
        
                  }


        
        
           74
        
        
          while
        
        (h<
        
          t)


        
        
           75
        
        
              {


        
        
           76
        
                 u=q[h++
        
          ];


        
        
           77
        
        
          for
        
        (
        
          int
        
         i=head[u];~i;i=
        
          next[i])


        
        
           78
        
        
                  {


        
        
           79
        
        
          in
        
        [to[i]]--
        
          ;


        
        
           80
        
        
          if
        
        (
        
          in
        
        [to[i]]==
        
          0
        
        ) q[t++]=
        
          to[i];


        
        
           81
        
        
          if
        
        (vis[to[i]]==u) 
        
          continue
        
        ;
        
          //
        
        
          有重边!! 
        
        
           82
        
        
          if
        
        (dp[to[i]]<dp[u]+
        
          val[to[i]])


        
        
           83
        
        
                      {


        
        
           84
        
                         dp[to[i]]=dp[u]+
        
          val[to[i]];


        
        
           85
        
                         num[to[i]]=
        
          num[u];


        
        
           86
        
        
                      }


        
        
           87
        
        
          else
        
        
          if
        
        (dp[to[i]]==dp[u]+
        
          val[to[i]])


        
        
           88
        
        
                      {


        
        
           89
        
                         num[to[i]]=(num[to[i]]+num[u])%
        
          mod;


        
        
           90
        
        
                      }


        
        
           91
        
                     vis[to[i]]=
        
          u;


        
        
           92
        
        
                  }


        
        
           93
        
        
              }


        
        
           94
        
        
          }


        
        
           95
        
        
           96
        
         inline 
        
          void
        
        
           go()


        
        
           97
        
        
          {


        
        
           98
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=n;i++
        
          )


        
        
           99
        
        
          if
        
        (!
        
          dfn[i]) dfs(i);


        
        
          100
        
             memset(head,-
        
          1
        
        ,
        
          sizeof
        
         head); cnt=
        
          0
        
        
          ;


        
        
          101
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=m;i++
        
          )


        
        
          102
        
        
          if
        
        (belong[st[i]]!=
        
          belong[ed[i]])


        
        
          103
        
        
                  {


        
        
          104
        
        
                      add(belong[st[i]],belong[ed[i]]);


        
        
          105
        
        
          in
        
        [belong[ed[i]]]++
        
          ;


        
        
          106
        
        
                  }


        
        
          107
        
        
              topsort();


        
        
          108
        
        
          for
        
        (
        
          int
        
         i=
        
          1
        
        ;i<=divg;i++
        
          )


        
        
          109
        
        
              {


        
        
          110
        
        
          if
        
        (dp[i]>
        
          ans)


        
        
          111
        
        
                  {


        
        
          112
        
                     ans=
        
          dp[i];


        
        
          113
        
                     ansnum=
        
          num[i];


        
        
          114
        
        
                  }


        
        
          115
        
        
          else
        
        
          if
        
        (dp[i]==ans) ansnum=(ansnum+num[i])%
        
          mod;


        
        
          116
        
        
              }


        
        
          117
        
             printf(
        
          "
        
        
          %d\n%d\n
        
        
          "
        
        
          ,ans,ansnum);


        
        
          118
        
        
          }


        
        
          119
        
        
          120
        
        
          int
        
        
           main()


        
        
          121
        
        
          {


        
        
          122
        
        
              read();


        
        
          123
        
        
              go();


        
        
          124
        
        
          return
        
        
          0
        
        
          ;


        
        
          125
        
         }
      

 

 

BZOJ 1093 [ZJOI2007]最大半连通子图


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论