标签:
先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 */
标签:
原文地址:http://www.cnblogs.com/leni/p/4869723.html