100pts但是hack没过(悬赏关注)
查看原帖
100pts但是hack没过(悬赏关注)
461616
Judgelight楼主2022/9/2 23:46
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<bitset>
#define N 2009
#define M N*N
using namespace std;
int n,m,cnt,din[N],scc_cnt,timestamps,dfn[N],low[N],he[N],stk[N],in_stk[N],top,id[N],Size[N],ans,hE[N];
string s;
bitset<N>mp[N];
struct Edge{
    int ne,to;
}e[M],E[M];
void add(int u,int v){
    e[++cnt].ne=he[u];
    e[cnt].to=v;
    he[u]=cnt;
}
void add1(int u,int v){
    E[++cnt].ne=hE[u];
    E[cnt].to=v;
    hE[u]=cnt;
}
void tarjan(int u){
    dfn[u]=low[u]=++timestamps;
    stk[++top]=u,in_stk[u]=1;
    for(int i=he[u];i;i=e[i].ne){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(in_stk[v]){
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u]){
        int y;
        scc_cnt++;
        do{
            y=stk[top--];
            in_stk[y]=0;
            id[y]=scc_cnt;
            Size[scc_cnt]++;
        }
        while(y!=u);
    }
}
queue<int>q;
void topsort(){
    for(int i=1;i<=scc_cnt;i++){
        if(din[i]==0){
            q.push(i);
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=hE[u];i;i=E[i].ne){
            int v=E[i].to;
            mp[v]|=mp[u];
            din[v]--;
            if(din[v]==0){
                q.push(v);
            }
        }
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s;
        for(int j=0;j<s.size();j++){
            if(s[j]=='1'||i==(j+1)){
                add(i,j+1);
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]){
            tarjan(i);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=he[i];j;j=e[j].ne){
            int u=i,v=e[i].to;
            if(id[u]!=id[v]){
                add1(id[v],id[u]);
                din[id[u]]++;
            }
        }
    }
    for(int i=1;i<=scc_cnt;i++){
        mp[i][i]=1;
    }
    topsort();
    for(int i=1;i<=scc_cnt;i++){
        for(int j=1;j<=scc_cnt;j++){
            if(mp[i][j]){
                ans+=Size[i]*Size[j];
            }
        }
    }
    cout<<ans;
    return 0;
}
2022/9/2 23:46
加载中...