社区讨论

我是OI 刚学萌新 bzojWA了 求助

P4306[JSOI2010] 连通数参与者 10已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@mi7cgycn
此快照首次捕获于
2025/11/20 19:25
4 个月前
此快照最后确认于
2025/11/20 20:30
4 个月前
查看原帖
两种写法 一个T(注释) 一个WA 绝望了(洛谷ac)
CPP
#include<bits/stdc++.h>
#define N 2005
using namespace std;
template<class T>
inline void read(T &x)
{
	x=0;
	static char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch))	x=x*10+ch-'0',ch=getchar();
}
struct Edge
{
	int to,next;
}edge[N*N];
int first[N],tot;
inline void addedge(int x,int y)
{
	tot++;
	edge[tot].to=y; edge[tot].next=first[x]; first[x]=tot;
}
char s[N];
int n,low[N],dfn[N],sign,belong[N],cnt,num[N],in[N],sum[N];
stack<int> sta;
bool insta[N],added[N][N];
inline void dfs1(int now)
{
	low[now]=dfn[now]=++sign;
	sta.push(now);
	insta[now]=true;
	for(int u=first[now];u;u=edge[u].next)
	{
		int vis=edge[u].to;
		if(!dfn[vis])
		{
			dfs1(vis);
			low[now]=min(low[vis],low[now]);
		}
		else if(insta[vis])	low[now]=min(dfn[vis],low[now]);
	}
	if(low[now]==dfn[now])
	{
		cnt++;
		int temp;
		do
		{
			temp=sta.top();
			insta[temp]=false;
			sta.pop();
			belong[temp]=cnt;
			num[cnt]++;
			sum[cnt]++;
		}while(temp!=now);
	}
}
vector<int> scc[N];
/*void dfs2(int begin,int now)
{
	ans[begin]+=num[now];
	for(int i=0;i<scc[now].size();i++)
	{
		int vis=scc[now][i];
		dfs2(begin,vis);
	}
}*/ 

void Topo_sort()
{
	//递推:每个SCC带来的贡献为能到达他的点数*size 
	queue <int> q;
	for(int i=1;i<=cnt;i++)	if(!in[i])	q.push(i);
	int ans=0;
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		ans+=sum[now]*num[now];
		for(int i=0;i<scc[now].size();i++)
		{
			int vis=scc[now][i];
			in[vis]--;	
			sum[vis]+=sum[now];
			if(!in[vis])	q.push(vis);
		}	
	}
	cout<<ans;
}
int main()
{
	read(n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
		for(int j=1;j<=n;j++)	if(s[j]=='1') addedge(i,j);
	}
	for(int i=1;i<=n;i++)	if(!dfn[i]) dfs1(i);
	/*	for(int i=1;i<=n;i++)
	{
		for(int u=first[i];u;u=edge[u].next)
		{
			int vis=edge[u].to;
			if(belong[i]!=belong[vis]&&!added[belong[i]][belong[vis]])	
				scc[belong[i]].push_back(belong[vis]),added[belong[i]][belong[vis]]=true;
		}	
	}

	//每个联通块的贡献是他能到达的SCC的num之和 
	int sum=0;
	//ans[i]:编号为i的SCC能到达的点的个数 
	for(int i=1;i<=n;i++)
		dfs2(belong[i],belong[i]);
	for(int i=1;i<=cnt;i++) sum+=ans[i];
	cout<<sum;*/			//以上是假做法 bzojT成狗 
	for(int i=1;i<=n;i++)
	{
		for(int u=first[i];u;u=edge[u].next)
		{
			int vis=edge[u].to;
			if(belong[i]!=belong[vis]&&!added[belong[i]][belong[vis]])	
				scc[belong[i]].push_back(belong[vis]),in[belong[vis]]++,added[belong[i]][belong[vis]]=true;
		}	
	}
	Topo_sort();
	return 0;
} 

回复

11 条回复,欢迎继续交流。

正在加载回复...