bzoj2208 [Jsoi2010]连通数(scc+bitset)
来源:互联网 发布:mac 命令行 文件夹 编辑:程序博客网 时间:2024/06/05 23:40
2208: [Jsoi2010]连通数
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1879 Solved: 778
[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
第一轮
【思路】
强连通分量+bitset传递闭包。
求出scc,缩点。对于新的DAG,如果两个scc之间相连则ans+=sccsz[i]*sccsz[j]。利用bitset与递推判断相连。
【代码】
1 #include<cstdio> 2 #include<bitset> 3 #include<queue> 4 #include<stack> 5 #include<vector> 6 #include<cstring> 7 #include<iostream> 8 using namespace std; 9 10 const int maxn = 2000+10;11 12 int pre[maxn],lowlink[maxn],sccno[maxn],sccsz[maxn],dfs_clock,scc_cnt;13 vector<int> G[maxn];14 stack<int> S;15 16 int dfs(int u) {17 pre[u]=lowlink[u]=++dfs_clock;18 S.push(u);19 for(int i=0;i<G[u].size();i++) {20 int v=G[u][i];21 if(!pre[v]) {22 dfs(v);23 lowlink[u]=min(lowlink[u],lowlink[v]);24 }25 else if(!sccno[v]) {26 lowlink[u]=min(lowlink[u],pre[v]);27 }28 }29 if(lowlink[u]==pre[u]) {30 scc_cnt++;31 for(;;) {32 int x=S.top(); S.pop();33 sccno[x]=scc_cnt;34 sccsz[scc_cnt]++;35 if(x==u) break;36 }37 }38 }39 void find_scc(int n) {40 memset(pre,0,sizeof(pre));41 memset(sccsz,0,sizeof(sccsz));42 memset(sccno,0,sizeof(sccno));43 scc_cnt=dfs_clock=0;44 for(int i=0;i<n;i++) 45 if(!pre[i]) dfs(i);46 }47 48 bitset<maxn> f[maxn]; //使用bitset 49 int n,in[maxn];50 char s[maxn];51 52 vector<int> Gx[maxn];53 void rebuild() {54 for(int i=1;i<=scc_cnt;i++) in[i]=0;55 for(int i=0;i<n;i++) {56 int u=sccno[i];57 for(int j=0;j<G[i].size();j++) {58 int v=sccno[G[i][j]];59 if(u!=v) Gx[u].push_back(v),in[v]++;60 }61 }62 }63 64 queue<int> q;65 void solve() {66 for(int i=1;i<=scc_cnt;i++) f[i][i]=1;67 for(int i=1;i<=scc_cnt;i++) if(!in[i]) q.push(i);68 while(!q.empty()) {69 int u=q.front(); q.pop();70 for(int i=0;i<Gx[u].size();i++) {71 int v=Gx[u][i];72 f[v]|=f[u]; //传递闭包73 if((--in[v])==0) q.push(v);74 }75 }76 }77 78 int main() {79 scanf("%d",&n);80 for(int i=0;i<n;i++){81 scanf("%s",s);82 for(int j=0;j<n;j++) {83 if(s[j]-'0') G[i].push_back(j);84 }85 }86 find_scc(n);87 rebuild();88 solve();89 int ans=0;90 for(int i=1;i<=scc_cnt;i++)91 {92 for(int j=1;j<=scc_cnt;j++)93 if(f[i][j]) ans+=sccsz[i]*sccsz[j];94 }95 printf("%d\n",ans);96 return 0;97 }
0 0
- bzoj2208 [Jsoi2010]连通数(scc+bitset)
- 【BZOJ2208】[Jsoi2010]连通数【BFS/DFS】【SCC】
- [Tarjan+Bitset]BZOJ2208: [Jsoi2010]连通数
- BZOJ2208: [Jsoi2010]连通数
- BZOJ2208: [Jsoi2010]连通数
- bzoj2208 [Jsoi2010]连通数
- bzoj2208: [Jsoi2010]连通数
- BZOJ2208 [Jsoi2010]连通数
- 【传递闭包+bitset优化】BZOJ2208 [Jsoi2010]连通数
- [BZOJ2208][Jsoi2010]连通数(tarjan+topdp)
- bzoj2208 [Jsoi2010]连通数(tarjan缩点+拓扑排序+bitset传递闭包)
- bzoj2208 [Jsoi2010]连通数 dfs
- [BZOJ2208][Jsoi2010]连通数(dfs||tarjan+拓扑序+dp)
- 【BZOJ2208】【JSOI2010】连通数 传递闭包
- 2208: [Jsoi2010]连通数(Trajan+bitset)
- BZOJ2208: [Jsoi2010]连通数 Tarjan缩点+Dfs
- bzoj 2208 [Jsoi2010]连通数 bitset
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- IllegalStateException: Can not perform this action after onSaveInstanceState
- lightoj 1145 - Dice (I) 前缀和优化DP
- UVAlive4287 Proving Equivalences(scc)
- UVAlive3211 Now or later(2-SAT)
- UVAlive3713 Astronauts(2-SAT)
- bzoj2208 [Jsoi2010]连通数(scc+bitset)
- bzoj1823 [JSOI2010]满汉全席(2-SAT)
- 如何获取IMEI号和MEID号
- 1022D进制的A+B
- uoj#67. 新年的毒瘤(割顶)
- dp入门
- JPEG图像压缩算法流程详解
- UVa10779 Collectors Problem(最大流)
- UVa11248 Frequency Hopping(最大流+最小割)