http://codeforces.com/gym/101630/attachments
给m条有向边 选其中2*n条构成一个强连通分量
队友想到的 跑两遍以1为起点的bfs 第一遍在原图上选出n-1条边 保证1可达2-n 第二遍反向建图 保证2-n可达1
把两遍选中的边凑在一起 任一点都是与1互相可达的 那整个图就两两互相可达了
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=1e5+10;
struct node1
{
int u,v;
};
struct node2
{
int id,v,next;
};
node1 pre[maxm];
node2 edge[maxm];
int first[maxn],book[maxn],vis[maxn];
int n,m,num;
void addedge(int id,int u,int v)
{
edge[num].id=id;
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
}
void dfs(int cur)
{
int i,id,v;
for(i=first[cur];i!=-1;i=edge[i].next){
id=edge[i].id,v=edge[i].v;
if(!vis[v]){
book[id]++,vis[v]=1;
dfs(v);
}
}
}
int main()
{
int t,i,cnt;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d%d",&pre[i].u,&pre[i].v);
for(i=1;i<=m;i++) book[i]=0;
for(i=1;i<=n;i++){
first[i]=-1;
vis[i]=0;
}
num=0;
for(i=1;i<=m;i++) addedge(i,pre[i].u,pre[i].v);
vis[1]=1;
dfs(1);
for(i=1;i<=n;i++){
first[i]=-1;
vis[i]=0;
}
num=0;
for(i=1;i<=m;i++) addedge(i,pre[i].v,pre[i].u);
vis[1]=1;
dfs(1);
cnt=m-2*n;
for(i=1;i<=m&&cnt>0;i++){
if(book[i]==0){
printf("%d %d\n",pre[i].u,pre[i].v);
cnt--;
}
}
}
return 0;
}