码迷,mamicode.com
首页 > Web开发 > 详细

[Jsoi2010]连通数

时间:2015-10-11 19:36:32      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:

先Tarjan缩点,然后建反图拓扑看每一个点可以由哪里经过,用到bitset定义zt状态压缩一下,拓扑图中x->y :则表示y可以到达x,所以zt[y]=zt[y]|zt[x]就知道了y的,然后在for一下每个点及其所到达的点, Cgema算出两两乘积得出ans。

 

技术分享
  1 #define MAXN 2010UL
  2 
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 #include<iostream>
  7 #define MIN(a,b) (a)<(b)?(a):(b);
  8 using namespace std;
  9 
 10 int n,head[MAXN],cnt,id,sum;
 11 char key;
 12 int dfn[MAXN],low[MAXN],bel[MAXN],front[MAXN],ans;
 13 int sta[MAXN],tail;
 14 bool vis[MAXN];
 15 bool exi[MAXN][MAXN];
 16 int indu[MAXN];
 17 int be[MAXN];
 18 int ge[MAXN];
 19 queue<int>st;
 20 struct Node{
 21     int en,to;
 22 }eda[4000005];
 23 struct A{
 24     int en,to;
 25 }sg[2000005];
 26 int op=0;
 27 void Add(int x,int y){
 28     eda[++cnt].to=head[x];
 29     eda[cnt].en=y;
 30     head[x]=cnt;
 31 }
 32 void Add2(int x,int y){
 33     sg[++cnt].to=front[x];
 34     sg[cnt].en=y;
 35     front[x]=cnt;
 36 }
 37 int Tarjan(int x){
 38     dfn[x]=++id;
 39     low[x]=id;
 40     vis[x]=1;
 41     sta[++tail]=x;
 42     for(int i=head[x];i;i=eda[i].to){
 43         int y=eda[i].en;
 44         if(!dfn[y]){
 45             Tarjan(y);
 46             low[x]=MIN(low[x],low[y]);
 47         }else if(vis[y]){
 48             low[x]=MIN(dfn[y],low[x]);
 49         }
 50     }
 51     if(dfn[x]==low[x]){
 52         sum++;
 53         while(sta[tail]!=x&&tail){
 54             bel[sta[tail]]=sum;
 55             vis[sta[tail]]=0;
 56             tail--;
 57         }
 58         bel[sta[tail]]=sum;
 59         vis[sta[tail]]=0;
 60         tail--;
 61     }    
 62 }
 63 int dfs(int x){
 64 //    printf("%d\n",x);
 65     op+=ge[x];
 66     vis[x]=1;
 67     for(int i=front[x];i;i=sg[i].to){
 68         if(!vis[sg[i].en])
 69             dfs(sg[i].en);
 70     }
 71 }
 72 int main(){
 73     freopen("connect.in","r",stdin);
 74     freopen("connect.out","w",stdout);
 75     scanf("%d",&n);
 76     for(int i=1;i<=n;i++){
 77         for(int j=1;j<=n;j++){
 78             cin>>key;
 79             if(key==1)    Add(i,j);
 80         }
 81     }
 82     for(int i=1;i<=n;i++){
 83         if(!dfn[i]) Tarjan(i);
 84     }    
 85     for(int i=1;i<=n;i++){
 86         ge[bel[i]]++;
 87         be[bel[i]]++;
 88         printf("%d belong to %d\n",i,bel[i]);
 89     }
 90     cnt=0;
 91     for(int i=1;i<=n;i++){
 92         for(int j=head[i];j;j=eda[j].to){
 93             int y=bel[eda[j].en];
 94     //        printf("%d -> %d\n",i,eda[j].en);
 95             if(!exi[bel[i]][y]&&y!=bel[i]){
 96                 Add2(y,bel[i]);
 97                 indu[bel[i]]++;
 98                 exi[bel[i]][y]=1;
 99             }
100         }
101     }
102     for(int i=1;i<=sum;i++){
103         printf("%d\n",indu[i]);
104         if(indu[i]==0) st.push(i);
105     } 
106     while(!st.empty()){
107         int u=st.front();
108         ans+=be[u]*ge[u];
109         for(int j=front[u];j;j=sg[j].to){
110             int y=sg[j].en;
111             indu[y]--;
112             ge[y]+=ge[u];
113              if(!indu[y]) st.push(y);
114         }
115         st.pop();
116     }
117     printf("%d",ans);
118 }
119 /*
120 5
121 01100
122 00101
123 00011
124 00000
125 00000
126 */
View Code

 

[Jsoi2010]连通数

标签:

原文地址:http://www.cnblogs.com/leni/p/4869723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!