Gym-101630C:Connections ###K ###K //K

题目链接:https://codeforces.ml/gym/101630/attachments

题意:给定一个有向图, 有m条边,问删掉m-2*n条边 后 即剩下2*n条边 后如何还保持图的连通的, 即任意一个点可以到达任意一个其他点,输出所有删掉的边

思路:随便选一个根节点开始dfs 得到的是一棵树 n-1条边, 再在根节点反方向跑一遍,又得到一棵树 共2*n-2条边, 这两棵树可以保证图是连通的

因为 正向跑一遍 说明根节点可以到达所有其他点, 反向建边跑一遍说明所有其他点可以到达根结点,那么根节点就满足可以到达任意点,

而其他任一点又可以先到达根节点再到达其他任意点

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =1e5+10;
 6 const int mod=1e9+7;
 7 vector<int>E[maxn];
 8 vector<int>G[maxn];
 9 int vis[maxn];
10 int n,m;//
11 map<pair<int,int>,int>mp;
12 
13 void dfs(int u)
14 {
15     vis[u]=1;
16     for(auto &v:E[u])
17     {
18         if(vis[v])
19             continue;
20         mp[{u,v}]=1;
21         dfs(v);
22     }
23 }
24 
25 void dfs222(int u)
26 {
27     vis[u]=1;
28     for(auto &v:G[u])
29     {
30         if(vis[v])
31             continue;
32         mp[{v,u}]=1;
33         dfs222(v);
34     }
35 }
36 
37 
38 
39 
40 int main()
41 {
42     ios::sync_with_stdio(false);
43     cin.tie(0);
44     int t;
45     cin>>t;
46     while(t--)
47     {
48         cin>>n>>m;
49         for(int i=1;i<=n;i++)
50            E[i].clear(),G[i].clear(),vis[i]=0;
51         mp.clear();
52         for(int i=0;i<m;i++)
53         {
54             int u,v;
55             cin>>u>>v;
56             E[u].pb(v);
57             G[v].pb(u);
58         }
59         dfs(1);
60         for(int i=1;i<=n;i++)
61             vis[i]=0;
62         dfs222(1);
63         int sum=m-2*n;
64         for(int i=1;i<=n;i++)
65         {
66             for(auto &v:E[i])
67             {
68                 if(sum&&!mp[{i,v}])
69                 {
70                     cout<<i<<" "<<v<<'\n';
71                     sum--;
72                 }
73             }
74         }
75     }
76 
77 
78 
79 }
View Code

 

posted @ 2020-10-04 09:48  canwinfor  阅读(135)  评论(0)    收藏  举报