您的位置:首页 > 其它

EOJ 3464/NEERC 2017 C.Connections【Kosaraju求强连通分量】

2018-03-04 22:57 309 查看
http://acm.ecnu.edu.cn/problem/3464/

给定一个n个点m条边的图,要求删掉一些边使得图仍然强连通且只剩2n条边。问删去哪些边。

我觉得这就是一题Kosaraju模板题。。随便选个点dfs,然后反向建图再让所有点往刚才选的这个点dfs,这样经过的边就是必须留下的边了。尽管没有tarjan那么简单,但实际上还是不难理解的。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
struct node
{
int to, index;
};
int u[maxn], v[maxn];
vector<node> g1[maxn], g2[maxn];
bool cut[maxn], vis[maxn];

void dfs(int now, vector<node>* g)
{
vis[now] = true;
for (auto &i: g[now])
{
if(vis[i.to]) continue;
cut[i.index] = true;
dfs(i.to, g);
}
}

int main()
{
int t, n, m;
cin >> t;
while (t--)
{
memset(cut, false, sizeof cut);
memset(vis, false, sizeof vis);
scanf("%d%d", &n, &m);
for (int i = 0; i <= n; ++i)
{
g1[i].clear();
g2[i].clear();
}
node p;
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", u+i, v+i);
p.to = v[i];
p.index = i;
g1[u[i]].push_back(p);

p.to = u[i];
p.index = i;
g2[v[i]].push_back(p);
}
dfs(1, g1);
memset(vis, false, sizeof vis);
dfs(1, g2);
int cnt = m-2*n;
for (int i = 1; i <= m && cnt; ++i)
if (!cut[i])
{
--cnt;
printf("%d %d\n", u[i], v[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: