您的位置:首页 > Web前端 > JavaScript

[Jsoi2010]连通数

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

#define MAXN 2010UL

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#define MIN(a,b) (a)<(b)?(a):(b);
using namespace std;

int n,head[MAXN],cnt,id,sum;
char key;
int dfn[MAXN],low[MAXN],bel[MAXN],front[MAXN],ans;
int sta[MAXN],tail;
bool vis[MAXN];
bool exi[MAXN][MAXN];
int indu[MAXN];
int be[MAXN];
int ge[MAXN];
queue<int>st;
struct Node{
int en,to;
}eda[4000005];
struct A{
int en,to;
}sg[2000005];
int op=0;
void Add(int x,int y){
eda[++cnt].to=head[x];
eda[cnt].en=y;
head[x]=cnt;
}
void Add2(int x,int y){
sg[++cnt].to=front[x];
sg[cnt].en=y;
front[x]=cnt;
}
int Tarjan(int x){
dfn[x]=++id;
low[x]=id;
vis[x]=1;
sta[++tail]=x;
for(int i=head[x];i;i=eda[i].to){
int y=eda[i].en;
if(!dfn[y]){
Tarjan(y);
low[x]=MIN(low[x],low[y]);
}else if(vis[y]){
low[x]=MIN(dfn[y],low[x]);
}
}
if(dfn[x]==low[x]){
sum++;
while(sta[tail]!=x&&tail){
bel[sta[tail]]=sum;
vis[sta[tail]]=0;
tail--;
}
bel[sta[tail]]=sum;
vis[sta[tail]]=0;
tail--;
}
}
int dfs(int x){
//    printf("%d\n",x);
op+=ge[x];
vis[x]=1;
for(int i=front[x];i;i=sg[i].to){
if(!vis[sg[i].en])
dfs(sg[i].en);
}
}
int main(){
freopen("connect.in","r",stdin);
freopen("connect.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>key;
if(key=='1')    Add(i,j);
}
}
for(int i=1;i<=n;i++){
if(!dfn[i]) Tarjan(i);
}
for(int i=1;i<=n;i++){
ge[bel[i]]++;
be[bel[i]]++;
printf("%d belong to %d\n",i,bel[i]);
}
cnt=0;
for(int i=1;i<=n;i++){
for(int j=head[i];j;j=eda[j].to){
int y=bel[eda[j].en];
//        printf("%d -> %d\n",i,eda[j].en);
if(!exi[bel[i]][y]&&y!=bel[i]){
Add2(y,bel[i]);
indu[bel[i]]++;
exi[bel[i]][y]=1;
}
}
}
for(int i=1;i<=sum;i++){
printf("%d\n",indu[i]);
if(indu[i]==0) st.push(i);
}
while(!st.empty()){
int u=st.front();
ans+=be[u]*ge[u];
for(int j=front[u];j;j=sg[j].to){
int y=sg[j].en;
indu[y]--;
ge[y]+=ge[u];
if(!indu[y]) st.push(y);
}
st.pop();
}
printf("%d",ans);
}
/*
5
01100
00101
00011
00000
00000
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: