zoukankan      html  css  js  c++  java
  • bzoj2208[Jsoi2010]连通数

    bzoj2208[Jsoi2010]连通数

    题意:

    给一个有向图,每个点对答案的贡献为该点可达的点个数,求答案。n≤2000,m≤4000000。

    题解:

    听说暴力可过QAQ不过为了练tanjan还是写了常规写法。

    先缩点,接着对每个入度为0的点做dp,每个点维护一个bitset。对于当前点,先将该点对应bitset的该点位置置为1,之后将这个bitset与该点所有子节点的bitset合并,然后枚举每个点,如果该点对应在bitset位置为1,则答案加上当前点的在原图中代表的点个数*该点在原图中代表的点个数。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <bitset>
     6 #define inc(i,j,k) for(int i=j;i<=k;i++)
     7 #define maxn 2010
     8 using namespace std;
     9 
    10 inline int read(){
    11     char ch=getchar(); int f=1,x=0;
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    13     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    14     return f*x;
    15 }
    16 struct e{int t,n;}es[2][maxn*maxn]; int ess[2],g[2][maxn];
    17 void pe(int f,int t,bool o){
    18     es[o][++ess[o]]=(e){t,g[o][f]}; g[o][f]=ess[o];
    19 }
    20 int dfn[maxn],low[maxn],tim,scc[maxn],sz[maxn],tot,ans,n; bool ins[maxn],not0[maxn]; stack<int>st;
    21 void tarjan(int x){
    22     dfn[x]=low[x]=++tim; ins[x]=1; st.push(x);
    23     for(int i=g[0][x];i;i=es[0][i].n){
    24         if(!dfn[es[0][i].t])tarjan(es[0][i].t),low[x]=min(low[x],low[es[0][i].t]);
    25         else if(ins[es[0][i].t])low[x]=min(low[x],dfn[es[0][i].t]);
    26     }
    27     if(dfn[x]==low[x]){
    28         tot++; while(1){int y=st.top(); st.pop(); ins[y]=0; scc[y]=tot; sz[tot]++; if(x==y)break;}
    29     }
    30 }
    31 bitset<maxn>bs[maxn]; bool vis[maxn];
    32 void dfs(int x){
    33     vis[x]=1; bs[x][x]=1;
    34     for(int i=g[1][x];i;i=es[1][i].n){if(!vis[es[1][i].t])dfs(es[1][i].t); bs[x]|=bs[es[1][i].t];}
    35     inc(i,1,tot)if(bs[x][i])ans+=sz[x]*sz[i];
    36 }
    37 char s[maxn];
    38 int main(){
    39     n=read(); inc(i,1,n){scanf("%s",s+1); inc(j,1,n)if(s[j]-'0')pe(i,j,0);} inc(i,1,n)if(!dfn[i])tarjan(i);
    40     inc(i,1,n)
    41         for(int j=g[0][i];j;j=es[0][j].n)
    42             if(scc[i]!=scc[es[0][j].t])pe(scc[i],scc[es[0][j].t],1),not0[scc[es[0][j].t]]=1;
    43     inc(i,1,tot)if(!not0[i])dfs(i); printf("%d",ans); return 0;
    44 }

    20161115

  • 相关阅读:
    PyQt5 控件学习(一个一个学习之QCommandLinkButton)
    多任务--线程
    PyQt5 控件学习(一个一个学习之QPushButton)
    PyQt5 控件学习(一个一个学习之QAbstractButton)
    再测我心中的事
    花了两天时间,整理了代码,封装了逻辑
    我现在发现,我写代码有严重的问题
    2014年8月2日0时13分22秒
    2014年8月2日15时13分4秒
    交警与货车司机
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/6067396.html
Copyright © 2011-2022 走看看