#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2050,M=N*N;
int head[N],ver[M],nxt[M],idx;
void add(int u,int v){
ver[idx]=v,nxt[idx]=head[u],head[u]=idx++;
}
void init(){
memset(head,-1,sizeof head);
memset(ver,0,sizeof ver);
memset(nxt,0,sizeof nxt);
idx=0;
}
string s;
int dfn[N],low[N],num,cnt,stk[N],top,bel[N],cap[N];
bool vis[N];
int du[N],n;
bitset<N> h[N];
void topsort(){
queue<int> q;
for(int i=1;i<=num;++i) if(!du[i]) q.push(i);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];~i;i=nxt[i]){
int y=ver[i];
h[y]|=h[x];
du[y]--;
if(!du[y]) q.push(y);
}
}
}
void tarjan(int x){
dfn[x]=low[x]=++cnt;
vis[x]=1;
stk[++top]=x;
for(int i=head[x];~i;i=nxt[i]){
int y=ver[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(vis[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
++num;
int y;
do{
y=stk[top--];
vis[y]=0;
bel[y]=num;
++cap[num];
}while(x!=y);
h[num][num]=1;
}
}
int main(){
//freopen("data.in","r",stdin);
//freopen("connect.out","w",stdout);
memset(head,-1,sizeof head);
scanf("%d",&n);
for(int i=1;i<=n;++i){
cin>>s;
for(int j=0;j<s.size();++j) if(s[j]=='1') add(i,j+1);
}
for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
init();
for(int x=1;x<=n;++x)
for(int i=head[x];~i;i=nxt[i]){
int y=ver[i];
if(bel[x]!=bel[y]) add(bel[y],bel[x]),du[bel[x]]++;
}
topsort();
int ans=0;
for(int i=1;i<=num;++i)
for(int j=1;j<=num;++j) if(h[i][j]) ans+=cap[i]*cap[j];
printf("%d",ans);
return 0;
}
我这是重建反图时,把链式前向星用到的数组全初始化了,但WA的杠杠的
但我用新的数组存图就AC了,哪位大佬给解释一下
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2050,M=N*N;
int head[N],ver[M],nxt[M],idx;
int headd[N],to[M],nxtt[M],tot;
void add(int u,int v){
ver[idx]=v,nxt[idx]=head[u],head[u]=idx++;
}
void add2(int u,int v){
to[tot]=v,nxtt[tot]=headd[u],headd[u]=tot++;
}
string s;
int dfn[N],low[N],num,cnt,stk[N],top,bel[N],cap[N];
bool vis[N];
int du[N],n;
bitset<N> h[N];
void topsort(){
queue<int> q;
for(int i=1;i<=num;++i) if(!du[i]) q.push(i);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=headd[x];~i;i=nxtt[i]){
int y=to[i];
h[y]|=h[x];
du[y]--;
if(!du[y]) q.push(y);
}
}
}
void tarjan(int x){
dfn[x]=low[x]=++cnt;
vis[x]=1;
stk[++top]=x;
for(int i=head[x];~i;i=nxt[i]){
int y=ver[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(vis[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
++num;
int y;
do{
y=stk[top--];
vis[y]=0;
bel[y]=num;
++cap[num];
}while(x!=y);
h[num][num]=1;
}
}
int main(){
//freopen("data.in","r",stdin);
//freopen("connect.out","w",stdout);
memset(head,-1,sizeof head);
memset(headd,-1,sizeof headd);
scanf("%d",&n);
for(int i=1;i<=n;++i){
cin>>s;
for(int j=0;j<s.size();++j) if(s[j]=='1') add(i,j+1);
}
for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
for(int x=1;x<=n;++x)
for(int i=head[x];~i;i=nxt[i]){
int y=ver[i];
if(bel[x]!=bel[y]) add2(bel[y],bel[x]),du[bel[x]]++;
}
topsort();
int ans=0;
for(int i=1;i<=num;++i)
for(int j=1;j<=num;++j) if(h[i][j]) ans+=cap[i]*cap[j];
printf("%d",ans);
return 0;
}