题目链接:https://odzkskevi.qnssl.com/c0c059d5732d43b0fe84c99caa5fb80f?v=1512491182
Problem C. Connections
Time limit: 3 seconds
Hard times are coming to Byteland. Quantum computing is becoming mainstream and Qubitland isgoing to occupy Byteland. The main problem is that Byteland does not have enough money for this war,so the King of Byteland Byteman 0x0B had decided to reform its road system to reduce expenses.
Byteland has n cities that are connected by m one-way roads and it is possible to get from any city toany other city using these roads. No two roads intersect outside of the cities and no other roads exist. Bythe way, roads are one-way because every road has a halfway barrier that may be passed in one directiononly. These barriers are intended to force enemies to waste their time if they choose the wrong way.
The idea of the upcoming road reform is to abandon some roads so that exactly 2n roads remain. Advisersof the King think that it should be enough to keep the ability to get from any city to any other city.(Maybe even less is enough? They do not know for sure.) The problem is how to choose roads to abandon.Everyone in Byteland knows that you are the only one who can solve this problem.
Input
Input consists of several test cases. The first line of the input contains the number of tests cases.
The first line of each test case contains n and m — the number of cities and the number of roadscorrespondingly (n ≥ 4, m > 2n). Each of the next m lines contains two numbers xi and yi denoting aroad from city xi to city yi (1 ≤ xi, yi ≤ n, xi ≠ yi). It is guaranteed that it is possible to get from anycity to any other city using existing roads only. For each pair (x, y) of cities there is at most one roadgoing from city x to city y and at most one road going from city y to city x. The solution is guaranteedto exist. The sum of m over all test cases in a single input does not exceed 100 000.
Output
For each test case output m − 2n lines. Each line describes a road that should be abandoned. Print theroad in the same format as in the input: the number of the source city and the number of the destinationcity. The order of roads in the output does not matter, but each road from the input may appear in theoutput at most once and each road in the output must have been in the input. It still must be possibleto get from any city to any other city using the remaining roads.
Example
input
1
4 9
1 2
1 3
2 3
2 4
3 2
3 4
4 1
4 2
4 3
output
1 3
题意:
给一个n个点,m(m>2*n,∑m<=100000)条边的有向图,请删除一些边使得剩下的边个数恰好为2*n条,并且保证n个点可以两两互达,输出删除方案。(保证给的图有解)
思路:
进行两边dfs,第一遍从任意一个点pos跑,跑到不能跑为止。第二遍所有边再建反向边(重新开一个图),再对pos点dfs,这样等价于除pos点以外的所有点向pos点跑。那些被访问过的边就是必须边,剩下的就是把那些不需要的删掉,直到满足要求为止。
因为题目保证有解,那么dfs一遍一定是一棵树,每一遍将被记录下n-1条边,因此两次后最多记录下2*n-2条边。
示例程序:
#include <bits/stdc++.h>
using namespace std;
struct jj
{
int u,v,next;
}w[100000],w1[100000];
int h[50000],h1[50000],visw[100000],vis[50000],numw,numw1;
void insert(int u,int v)
{
w[numw].u=u;
w[numw].v=v;
w[numw].next=h[u];
h[u]=numw++;
w1[numw1].v=u;
w1[numw1].next=h1[v];
h1[v]=numw1++;
}
void dfs(int t)
{
int i;
for(i=h[t];i!=-1;i=w[i].next)
{
if(vis[w[i].v]==0)
{
vis[w[i].v]=1;
visw[i]=1;
dfs(w[i].v);
}
}
}
void dfs1(int t)
{
int i;
for(i=h1[t];i!=-1;i=w1[i].next)
{
if(vis[w1[i].v]==0)
{
vis[w1[i].v]=1;
visw[i]=1;
dfs1(w1[i].v);
}
}
}
int main()
{
int t,x,y,i,i1,num,n,m;
scanf("%d",&t);
while(t--)
{
memset(h,-1,sizeof(h));
memset(h1,-1,sizeof(h1));
memset(visw,0,sizeof(visw)); //visw数组是记录哪些边被访问过,哪些没有被访问过
numw=0;
numw1=0;
scanf("%d %d",&n,&m);
for(i=1;m>=i;i++)
{
scanf("%d %d",&x,&y);
insert(x-1,y-1);
}
memset(vis,0,sizeof(vis));
dfs(0);
memset(vis,0,sizeof(vis));
dfs1(0);
num=m;
for(i=0;m>i&&num!=2*n;i++)
{
if(visw[i]==0)
{
num--;
printf("%d %d\n",w[i].u+1,w[i].v+1);
}
}
}
return 0;
}