Description
Solution
听说暴力可行?
n*m的复杂度或许可以水过。
然而我不为水分而来(高尚的人格==)
于是强联通分量分解一发,然后遍历图,算出答案(简单的树形dp)。
好像还是暴力的样子==
但是边和点都没有那么多了。
也就是说一定可以过掉的。
Code
/**************************************************************
Problem: 2208
User: bblss123
Language: C++
Result: Accepted
Time:5876 ms
Memory:14396 kb
****************************************************************/
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
using namespace std;
const int M=2e3+5;
#define pb push_back
#define vec vector<int>
vec edge[M],G[M];
char str[M];
int lowlink[M],sccid[M],dfs_clock,pre[M],sz[M],allc;
bool mark[M][M];
stack<int>stk;
inline void Min(int &a,int b){if(a>b)a=b;}
int ans=0;
void predfs(int v){
pre[v]=lowlink[v]=++dfs_clock;
stk.push(v);
for(int i=0;i<edge[v].size();++i){
int to=edge[v][i];
if(!pre[to])predfs(to),Min(lowlink[v],lowlink[to]);
else if(!sccid[to])Min(lowlink[v],pre[to]);
}
if(pre[v]==lowlink[v]){
sccid[v]=++allc;
int lar=0;
for(;!stk.empty();){
int k=stk.top();stk.pop();
++sz[allc];
sccid[k]=sccid[v];
if(k==v)break;
}
}
}
bool used[M];
int dfs(int v,int f,const int &s){
ans+=s*sz[v];
used[v]=1;
for(int i=0;i<G[v].size();++i){
int to=G[v][i];
if(to==f||used[to])continue;
dfs(to,v,s);
}
}
int main(){
int n;cin>>n;
for(int i=1;i<=n;++i){
scanf("%s",str+1);
for(int j=1;j<=n;++j)
if(str[j]=='1'&&j!=i)edge[i].pb(j);
}
for(int i=1;i<=n;++i)
if(!sccid[i])predfs(i);
for(int i=1;i<=n;++i)
for(int j=0;j<edge[i].size();++j)
if(!mark[sccid[i]][sccid[edge[i][j]]]&&sccid[edge[i][j]]!=sccid[i])
G[sccid[i]].pb(sccid[edge[i][j]]),mark[sccid[i]][sccid[edge[i][j]]]=1;
for(int i=1;i<=allc;++i){
memset(used,0,sizeof(used));
dfs(i,0,sz[i]);
}
cout<<ans<<endl;
return 0;
}