2208: [Jsoi2010]连通数
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3328 Solved: 1457
[Submit][Status][Discuss]
Description
Input
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
Output
输出一行一个整数,表示该图的连通数。
Sample Input
3
010
001
100
010
001
100
Sample Output
9
HINT
对于100%的数据,N不超过2000。
Source
暴力n^2是可以过得
正解是tarjin缩完点,递推一下
#include <bits/stdc++.h>
#define ll long long
#define eps 1e-7
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=5e6+10;
struct node{
int y,next;
}e[MAXN];
int linkk[MAXN],len=0,a[2010][2010],low[MAXN],dfs_clock=0,dfn[MAXN],cnt[MAXN],sum[MAXN],f[MAXN],tot=0,vis[2100],n,m,ine[MAXN],stark[MAXN],top=0;
inline void insert(int xx,int yy){
e[++len].y=yy;e[len].next=linkk[xx];linkk[xx]=len;
}
namespace zhangenming{
void tarjin(int st){
dfn[st]=low[st]=++dfs_clock;
vis[st]=1;stark[++top]=st;
for(int i=linkk[st];i;i=e[i].next){
if(!dfn[e[i].y]){
tarjin(e[i].y);
low[st]=min(low[st],low[e[i].y]);
}
else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]);
}
if(low[st]==dfn[st]){
++tot;
int k;
do{
k=stark[top--];
ine[k]=tot;
vis[k]=0;
sum[tot]++;
}while(k!=st);
}
}
void rebuild(){
len=0;memset(linkk,0,sizeof(linkk));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(ine[i]!=ine[j]&&a[i][j]){
insert(ine[i],ine[j]);
cnt[ine[j]]++;
}
}
}
}
void init(){
n=read();
for(int i=1;i<=n;i++){
char ch[2100];
scanf("%s",ch+1);
for(int j=1;j<=n;j++){
a[i][j]=ch[j]-'0';
if(a[i][j]) insert(i,j);
}
}
}
inline void dp(int st,int tn){
vis[st]=1;
for(int i=linkk[st];i;i=e[i].next){
if(!vis[e[i].y]) dp(e[i].y,tn);
}
f[tn]+=sum[st];
}
void solve(){
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjin(i);
}
rebuild();
//cout<<tot<<endl;
for(int i=1;i<=tot;i++){
memset(vis,0,sizeof(vis));
dp(i,i);
}
ll ans=0;
for(int i=1;i<=tot;i++){
ans+=(sum[i]*f[i]);
}
cout<<ans<<endl;
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("zh.out","w",stdout);
using namespace zhangenming;
init();
solve();
return 0;
}