社区讨论
我是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 条回复,欢迎继续交流。
正在加载回复...