Problem C. Connections
http://codeforces.com/gym/101630
给你n个点,m条有向边,问你只保留n-2*m条边,使整个图为全连通图
请输出不要的边,special judge
DFS正着扫一遍,反着扫一遍,要是这条边都没被扫到,就可以不要了
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxm=200010;
int n, m;
int head1[maxn], to1[maxm], from1[maxm], nxt1[maxm], tot1;
int head2[maxn], to2[maxm], from2[maxm], nxt2[maxm], tot2;
bool vis[maxn], vis1[maxn];
void addedge(int u, int v)
{
from1[tot1] = u;
to1[tot1] = v;
nxt1[tot1] = head1[u];
head1[u] = tot1++;
from2[tot2] = v;
to2[tot2] = u;
nxt2[tot2] = head2[v];
head2[v] = tot2++;
}
void dfs1(int t)
{
for(int i = head1[t]; i != -1; i = nxt1[i])
{
if(!vis[to1[i]])
{
vis1[i] = 1;
vis[to1[i]] = 1;
dfs1(to1[i]);
}
}
}
void dfs2(int t)
{
for(int i = head2[t]; i != -1; i = nxt2[i])
{
if(!vis[to2[i]])
{
vis1[i] = 1;
vis[to2[i]] = 1;
dfs2(to2[i]);
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
memset(head1, -1, sizeof head1);
memset(head2, -1, sizeof head2);
memset(vis, 0, sizeof vis);
memset(vis1, 0, sizeof vis1);
tot1 = 0, tot2 = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
addedge(u - 1, v - 1);
}
dfs1(0);
memset(vis, 0, sizeof vis);
dfs2(0);
int sum = m;
for(int i = 0; i < m && sum != 2 * n; i++)
{
if(!vis1[i])
{
sum--;
cout << from1[i] + 1 << " " << to1[i] + 1 <<endl;
}
}
}
return 0;
}