hdu5413 CRB and Roads(topo + bitset)
2016-07-18 23:04
363 查看
给定一张有向图,对于边e<u,v>,如果去掉它的话,u仍然可以到达v的话,那么这条边就是多余边。
显然的一个思路是倒着做。先topo一遍,然后倒着来,这里需要用到bitset(也是赛后才知道有这种东西)
显然的一个思路是倒着做。先topo一遍,然后倒着来,这里需要用到bitset(也是赛后才知道有这种东西)
const int maxn = 2e4 + 10; vector<vector<int> > G,mp; int in[maxn]; int rec[maxn]; int top; int n, m; void topo() { top = 0; for (int i = 1;i <= n;++i) if (in[i] == 0) rec[top++] = i; for (int i = 0;i < top;++i) { int u = rec[i]; int Size = G[u].size(); for (int j = 0;j < Size;++j) { int v = G[u][j]; mp[v].push_back(u); if (--in[v] == 0) rec[top++] = v; } } } bitset<maxn> bit[maxn]; int main(int argc, const char * argv[]) { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); // clock_t _ = clock(); int kase;cin >> kase; while(kase--) { cin >> n >> m; G.clear();G.resize(n + 2); mp.clear();mp.resize(n + 2); int u, v; memset(in, 0, sizeof in); for (int i = 1;i <= m;++i) { scanf("%d%d", &u, &v); G[u].push_back(v); in[v]++; } topo(); // for (int i = 0;i < top;++i) // cout << rec[i] << ' '; // cout << endl; for (int i = 0;i <= n;++i) { bit[i].reset(); bit[i].set(i); } // bit[2] |= bit[1]; // for (int i = 0;i <= n;++i) // cout << (bit[2][i]?1:0); // cout << endl; int ans = 0; for (int i = 0;i < top;++i) { int u = rec[i]; int Size = mp[u].size(); for (int j = 0;j < Size;++j) { int v = mp[u][j]; // printf("(%d, %d):", u, v); // cout << bit[u] << endl; // for (int k = 0;k <= n;++k) // cout << (bit[u][v]?1:0); // cout << endl; if (bit[u][v]) ans++; bit[u] |= bit[v];//dp } // cout << endl; } cout << ans << endl; } // printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC); return 0; }
相关文章推荐
- 关于bitset中低阶位与高阶位的理解
- 关于bitset中低阶位与高阶位的理解
- C++计算输入数据对应二进制中1的个数。
- C++习题整理(2)
- 讨论组12.20讲述内容笔记
- C++表达式
- cout的二进制输出实现
- C++标准库:bitset 用法整理 (来自网易 happyboy200032的博客)
- 位数组实现方法
- Bitmap
- Java BitSet类
- DES加密解密 使用bitset编写...
- c++ bitset 用法
- bitset应用---产生1万个不重复的随机数
- 位图法排序
- 位图法查找算法
- 剑指Offer--010-二进制中1的个数
- 算法之旅,直奔<bitset>之三 test
- 算法之旅,直奔<bitset>之四 set
- 算法之旅,直奔<bitset>之五 count