zoukankan      html  css  js  c++  java
  • BZOJ 1093 [ZJOI2007]最大半连通子图

    以前做过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 }
  • 相关阅读:
    Java nio Socket非阻塞模式
    Android执行文件apk的组成结构
    C++大会归来
    C++大会的入场卷已入手
    DVB vs. SVB+Shader & Instancing
    放一个半年前写的Python静态检查编译器
    GCC 4.1 Released
    C++大会后的一些感想
    多核技术来临?
    Notepad++ v3.3 released
  • 原文地址:https://www.cnblogs.com/proverbs/p/2867089.html
Copyright © 2011-2022 走看看