BZOJ 2208 Jsoi2010 连通数
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; }