题目链接
求有向图强连通分量的2n个边的边集
首先从1开始DFS可以走到的所有点,并记录走过的边
这样就满足了从1可达所有其他点
然后从1开始DFS走反向边,这样保证其他点可达1点.
两遍dfs
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
const int maxn = 1e5 +5 ;
struct node
{
int to;
int ind;
};
int u[maxn];
int v[maxn];
int ans[maxn];
vector <node> G[maxn];
vector <node> G1[maxn];
int T;
int n,m;
int vis[maxn];
void dfs(int cur)
{
vis[cur]=1 ;
for (int i=0 ;i<G[cur].size();i++)
{
if (vis[G[cur][i].to ]) continue ;
ans[ G[cur][i].ind ] = 1 ;
dfs(G[cur][i].to );
}
}
void dfs1(int cur)
{
vis[cur]=1 ;
for (int i=0 ;i<G1[cur].size();i++)
{
if (vis[G1[cur][i].to ]) continue ;
ans[ G1[cur][i].ind ] = 1 ;
dfs1(G1[cur][i].to );
}
}
int main()
{
scanf ("%d" ,&T);
while (T--)
{
memset (ans,0 ,sizeof (ans));
memset (vis,0 ,sizeof (vis));
scanf ("%d %d" ,&n,&m);
for (int i=0 ;i<=n;i++)
{
G[i].clear();
}
for (int i=0 ;i<=n;i++)
{
G1[i].clear();
}
node nt;
for (int i=1 ;i<=m;i++)
{
scanf ("%d %d" ,&u[i],&v[i]);
nt.to = v[i];
nt.ind = i;
G[u[i]].push_back(nt);
nt.to = u[i];
nt.ind = i;
G1[v[i]].push_back(nt);
}
dfs(1 );
memset (vis,0 ,sizeof (vis));
dfs1(1 );
int ct = m-2 *n;
for (int i=1 ;i<=m&&ct;i++)
{
if (!ans[i])
{
ct--;
printf ("%d %d\n" ,u[i],v[i]);
}
}
}
return 0 ;
}