链式前向星被我写出锅了
查看原帖
链式前向星被我写出锅了
581107
poppingW楼主2023/8/21 21:22

90分,后面的subtack2全WA了

#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;
}

2023/8/21 21:22
加载中...