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 }

浙公网安备 33010602011771号