【图论·强连通分量scc】hdu6072Logical Chain
来源:互联网 发布:手机淘宝设置在哪 编辑:程序博客网 时间:2024/05/22 16:39
非常有灵性的一道强连通分量。乍一看是道模板题,然而需要用bitset优化时间复杂度至1/64;bitset什么鬼啊喂,很佩服赛场上唯一做出来的大佬orz;
常规部分,学习了scc模板求强连通分量;
第一遍dfs给图上的倒序编号(最后访问到的标最小号);
第二遍在所有边反向后的图上dfs,从一个强连通分图上的点不可能访问到其他强分图上的点(为什么还没有理解)
cmp[I] = k 表示编号为i的点属于编号为k的强分图;
scc结束;
本题中节点数为t的强分图,对答案贡献t*(t-1)/2;
难点就是bitset 的理解和使用了(紧张);
首先试了下头文件#include
然而长度为8的bitset<8> b; 只能放8个0/1;
并不是很神奇;遂放弃,看大神的手写版;
这就非常有灵性了。
reset(int x) 好理解,初始化。x=0 b为0,x = 0xff,无限大;
flip(int x) 不好理解。8位,256个数,把x这个数0变1,1变0;
b[x>>5] 每一位表示32个数,x>>5确定x属于哪一位管;
将这一位加上2的x%32次方,表示这个数的存在
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstdio>#include<vector>#include<cstring>#include<stack>#include<queue>#include<bitset>using namespace std;using std::bitset;typedef long long ll;const int maxv = 255; struct BIT{ unsigned int b[8]; void reset(int x){ memset(b, x, sizeof(b)); } void flip(int x){ b[x >> 5] ^= 1U << (x & 31); } int get(int x){ return (b[x >> 5] >> (x & 31)) & 1; } }G[maxv], rG[maxv], vis;int V;vector<int> vs;int cmp[maxv];int cnt = 0;inline int ctz(unsigned int s){ int x = 0; while (!(s & 1)) { ++x; s >>= 1; } return x;}void dfs(int v){ vis.flip(v); unsigned int s; for (int i = 0; i < 8; ++i){ while (1){ s = vis.b[i] & G[v].b[i]; if (!s) break; //这里是什么原理依然没有搞清楚orz; dfs((i << 5)| ctz(s)); } } vs.push_back(v);}void rdfs(int v){ ++cnt; vis.flip(v); unsigned int s; for (int i = 0; i < 8; i++){ while (1){ s = vis.b[i] & rG[v].b[i]; if (!s) break; rdfs((i << 5 )| ctz(s)); } }}void scc(){ vis.reset(0xff);vs.clear(); for (int i = 0; i < V; i++){ if (vis.get(i)) dfs(i); } vis.reset(0xff); ll ans = 0; for (int i = vs.size() - 1; i >= 0; i--){ if (vis.get(vs[i])) { cnt = 0; rdfs(vs[i]); ans += cnt*(cnt - 1) / 2; } } printf("%lld\n", ans);}char c;int t, m;int main(){ scanf("%d", &t); while (t--){ scanf("%d%d", &V, &m); for (int i = 0; i <= V; i++){ G[i].reset(0); rG[i].reset(0); } for (int i = 0; i < V; i++){ char g[maxv]; scanf("%s", g); for (int j = 0; j < V; j++){ if (g[j] == '1') { G[i].flip(j); rG[j].flip(i); } } } while (m--){ int k; scanf("%d", &k); for (int i = 1; i <= k; ++i){ int u, v; scanf("%d%d", &u, &v); G[u - 1].flip(v - 1); rG[v - 1].flip(u - 1); } scc(); } }}
阅读全文
0 0
- 【图论·强连通分量scc】hdu6072Logical Chain
- 强连通分量scc
- 强连通分量SCC
- 强连通分量scc
- 强连通分量(SCC)详解
- 强连通分量SCC模版(LRJ)
- 【有向图强连通分量(SCC)】
- 强连通分量(SCC)的Tarjan算法
- 强连通分量(SCC)模版
- 强连通分量SCC(Tarjan)
- 有向图的强连通分量 SCC tarjin算法
- 强连通分量(SCC)Kosaraju算法学习笔记
- 有向图的强连通分量(SCC)
- SDUT-2170-The Largest SCC(强连通分量)
- [模板]拓扑排序, 强连通分量分解SCC
- Tarjan算法求解强连通分量(SCC)
- POJ-2186 Popular Cows (SCC 强连通分量)
- 不完全浅析Tarjan求强连通分量(SCC)
- 大小端模式
- 骨折愈合
- 啥是eMarketer公司
- 欢迎使用CSDN-markdown编辑器
- 我的实现_登录功能
- 【图论·强连通分量scc】hdu6072Logical Chain
- C语言的枚举与宏定义
- Struts2配置详解
- 用Runtime实现KVO
- Softmax回归
- 2017年8月8日
- 带头结点的单链表总结
- Bootstrap个人笔记
- java可变参数函数