【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数
2014-11-06 10:38
435 查看
两次dfs缩点,然后n次dfs暴搜。
#include<cstdio> #include<vector> #include<cstring> using namespace std; #define N 2001 vector<int>G ,rG ,vs,G2 ; typedef vector<int>::iterator ITER; char s[N+1][N+1]; int cmp ,sum,cnt ,ans,n; bool vis ; void dfs(int U) { vis[U]=1; for(ITER it=G[U].begin();it!=G[U].end();it++) if(!vis[*it]) dfs(*it); vs.push_back(U); } void dfs2(int U) { vis[U]=1; cmp[U]=sum; cnt[sum]++; for(ITER it=rG[U].begin();it!=rG[U].end();it++) if(!vis[*it]) dfs2(*it); } void scc() { for(int i=1;i<=n;i++) if(!vis[i]) dfs(i); memset(vis,0,sizeof(vis)); ITER it=vs.end(); it--; for(;;it--) { if(!vis[*it]) { sum++; dfs2(*it); } if(it==vs.begin()) break; } memset(vis,0,sizeof(vis)); } void dfs3(int U) { vis[U]=1; ans+=cnt[U]; for(ITER it=G2[U].begin();it!=G2[U].end();it++) if(!vis[*it]) dfs3(*it); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s[i]+1); for(int j=1;j<=n;j++) if(s[i][j]=='1') { G[i].push_back(j); G[j].push_back(i); } } scc(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(s[i][j]=='1'&&cmp[i]!=cmp[j]) G2[cmp[i]].push_back(cmp[j]); for(int i=1;i<=sum;i++) { memset(vis,0,sizeof(vis)); dfs3(i); } printf("%d\n",ans); return 0; }
相关文章推荐
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- 【bzoj2208】[Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数 - Tarjan_SCC/Floyd+bitset优化
- bzoj 2208: [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
- bzoj 2208: [Jsoi2010]连通数
- [bzoj2208][Jsoi2010]连通数_bitset_传递闭包floyd
- bzoj 2208: [Jsoi2010]连通数
- BZOJ 2208 JSOI 2010 连通数 Tarjan+bitset
- 【BZOJ】【2208】【JSOI2010】连通数
- 2208: [Jsoi2010]连通数 - BZOJ
- 【BZOJ2208】[Jsoi2010]连通数【BFS/DFS】【SCC】
- BZOJ 2208: [Jsoi2010]连通数
- BZOJ2208 [JSOI2010] 连通数
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- BZOJ 2208: [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- 暴力【bzoj2208】: [Jsoi2010]连通数