BZOJ 2208 JSOI 2010 连通数 Tarjan+bitset
来源:互联网 发布:二手mac pro工作站 编辑:程序博客网 时间:2024/06/06 00:48
题目大意:给出一张有向图,若一个点能够到达另一个点,那么说这两个点是一对联通点。问图中共有多少联通点。
思路:先进行一次Tarjan,求出所有的scc,对于一个scc中的点,对答案的贡献就是cnt^2,不同的scc组成了一张可拓扑图,然后对于每个scc维护一个bitset,来统计他自己和标号比它小的scc中共有多少个不同的点。然后进行dp,其中不停的或就可以了。
第一次使用bitset
CODE:
#include <bitset>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAXP 2010#define MAX 4000010using namespace std; int points;int head[MAXP],total;int next[MAX],aim[MAX]; inline void Add(int x,int y){ next[++total] = head[x]; aim[total] = y; head[x] = total;} int dfn[MAXP],low[MAXP],_clock;int stack[MAXP],top;bool in_stack[MAXP];int changed[MAXP],scc,num[MAXP];bitset<MAXP> have[MAXP]; void Tarjan(int x){ dfn[x] = low[x] = ++_clock; stack[++top] = x; in_stack[x] = true; for(int i = head[x]; i; i = next[i]) { if(!dfn[aim[i]]) Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]); else if(in_stack[aim[i]]) low[x] = min(low[x],dfn[aim[i]]); } if(dfn[x] == low[x]) { int temp; ++scc; do { temp = stack[top--]; in_stack[temp] = false; changed[temp] = scc; ++num[scc]; }while(temp != x); }} int main(){ cin >> points; for(int i = 1; i <= points; ++i) for(int x,j = 1; j <= points; ++j) { scanf("%1d",&x); if(x) Add(i,j); } for(int i = 1; i <= points; ++i) if(!dfn[i]) Tarjan(i); for(int i = 1; i <= points; ++i) have[changed[i]][i] = true; int ans = 0; for(int i = 1; i <= scc; ++i) { ans += num[i] * num[i]; bitset<MAXP> temp; for(int x = 1; x <= points; ++x) if(changed[x] == i) for(int j = head[x]; j; j = next[j]) if(changed[aim[j]] != i) temp |= have[changed[aim[j]]]; ans += num[i] * temp.count(); have[i] |= temp; } cout << ans << endl; return 0;}
0 0
- BZOJ 2208 JSOI 2010 连通数 Tarjan+bitset
- [tarjan+bitset]BZOJ 2208——[Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- bzoj 2208 [Jsoi2010]连通数 bitset
- [Tarjan+Bitset]BZOJ2208: [Jsoi2010]连通数
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- 【BZOJ】2208 连通数
- 2208: [Jsoi2010]连通数(Trajan+bitset)
- 【bzoj 2208】[Jsoi2010]连通数(dfs||Tarjan算法+拓扑序+dp)
- 2208: [Jsoi2010]连通数(tarjan + 状态压缩)
- bzoj2208 [Jsoi2010]连通数(tarjan缩点+拓扑排序+bitset传递闭包)
- bzoj 2208: [Jsoi2010]连通数
- 【BZOJ 2208】 [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数
- 织梦注册企业与个人账号分别使用不同模板
- postgresql 预写式日志(Write Ahead Long)
- 字符串和指针(一)
- Python之路——numpy各函数简介之生成数组函数(Array creation routines)
- 41 三个数从小到大排序
- BZOJ 2208 JSOI 2010 连通数 Tarjan+bitset
- Android开发者 须知道的两个网站
- C++ string的替换字符
- MySQL中给表添加一个字段(字段名、是否为空、默认值)
- struts2之单个文件上传
- javascript关闭弹出窗口时刷新父窗口和居中显示弹出窗
- MFC 之 OnClose 与 OnCancel
- 【环境】ruby换源
- Linux网络配置命令