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

posted @ 2016-11-15 21:24  YuanZiming  阅读(357)  评论(0编辑  收藏  举报