您的位置:首页 > 运维架构

hdu5413 CRB and Roads(topo + bitset)

2016-07-18 23:04 363 查看
给定一张有向图,对于边e<u,v>,如果去掉它的话,u仍然可以到达v的话,那么这条边就是多余边。

显然的一个思路是倒着做。先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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  topo排序 bitset