【BZOJ】【2208】【JSOI2010】连通数
2015-01-18 00:57
501 查看
题解:
1.Tarjan缩点以后对每个连通分量进行深搜,看能到哪些连通分量,能到达的所有连通分量的size之和记为sum。则第i个连通分量对答案的贡献为size[i]*sum(到其他连通分量)+size[i]*size[i](本身互相可达)
2.在网上搜了一下……这题可以直接dfs过……汗。“正解”是Tarjan缩点+拓扑排序+状态压缩
View Code
1.Tarjan缩点以后对每个连通分量进行深搜,看能到哪些连通分量,能到达的所有连通分量的size之和记为sum。则第i个连通分量对答案的贡献为size[i]*sum(到其他连通分量)+size[i]*size[i](本身互相可达)
2.在网上搜了一下……这题可以直接dfs过……汗。“正解”是Tarjan缩点+拓扑排序+状态压缩
/************************************************************** Problem: 2208 User: Tunix Language: C++ Result: Accepted Time:9476 ms Memory:64772 kb ****************************************************************/ //BZOJ 2208 #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define rep(i,n) for(int i=0;i<n;++i) #define F(i,j,n) for(int i=j;i<=n;++i) #define D(i,j,n) for(int i=j;i>=n;--i) using namespace std; const int N=2015; typedef long long LL; void read(int &v){ v=0; int sign=1; char ch=getchar(); while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();} while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();} v*=sign; } /*******************tamplate********************/ int to1[N*N],head1 ,next1[N*N],cnt=0; int to2[N*N],head2 ,next2[N*N]; void ins1(int x,int y){ to1[++cnt]=y; next1[cnt]=head1[x]; head1[x]=cnt; } void ins2(int x,int y){ to2[++cnt]=y; next2[cnt]=head2[x]; head2[x]=cnt; } /***********************************************/ int n,m; int dfn ,low ,dfs_clock=0,belong ,num,size ; int st ,top=0; bool in ; void tarjan(int x){ int y; dfn[x]=low[x]=++dfs_clock; st[top++]=x; in[x]=1; for(int i=head1[x];i;i=next1[i]){ y=to1[i]; if (!dfn[y]){ tarjan(y); low[x]=min(low[x],low[y]); } else if (in[y]) low[x]=min(low[x],dfn[y]); } if (low[x]==dfn[x]){ num++; size[num]=0; for(y=0;y!=x;){ y=st[--top]; in[y]=0; belong[y]=num; size[num]++; } } } void rebuild(){ cnt=0; F(x,1,n) for(int i=head1[x];i;i=next1[i]) if (belong[x]!=belong[to1[i]]) ins2(belong[x],belong[to1[i]]); } /***********************************************/ bool vis ; int sum=0; void dfs(int x){ int y; for(int i=head2[x];i;i=next2[i]){ y=to2[i]; if (!vis[y]){ vis[y]=1; sum+=size[y]; dfs(y); } } } void solve(){ LL ans=0; F(i,1,num){ memset(vis,0,sizeof vis); sum=0; dfs(i); ans+=size[i]*sum+size[i]*size[i]; } printf("%lld\n",ans); } int main(){ #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); #endif read(n); char s ; F(i,1,n){ scanf("%s",s); rep(j,strlen(s)) if (s[j]=='1') ins1(i,j+1); } F(i,1,n) if (!dfn[i]) tarjan(i); rebuild(); solve(); return 0; }
View Code
相关文章推荐
- BZOJ 2208: [Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数
- 【bzoj2208】[Jsoi2010]连通数
- [BZOJ2208][Jsoi2010]连通数(tarjan+topdp)
- bzoj 2208: [Jsoi2010]连通数
- bzoj2208 [Jsoi2010]连通数(tarjan缩点+拓扑排序+bitset传递闭包)
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- BZOJ 2208: [Jsoi2010]连通数( DFS )
- 2208: [Jsoi2010]连通数 - BZOJ
- [tarjan+bitset]BZOJ 2208——[Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- bzoj 2208 [Jsoi2010]连通数 bitset
- bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】
- [bzoj2208][Jsoi2010]连通数_bitset_传递闭包floyd
- BZOJ2208 [JSOI2010] 连通数
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- 【BZOJ2208】【JSOI2010】连通数 传递闭包
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
- bzoj2208 [Jsoi2010]连通数(scc+bitset)