zoukankan      html  css  js  c++  java
  • Gym101630C Connections

    题目大意:

      给出一个(n)个点(m)条边的有向图,无自环无重边。要求把这个图进行删边,直到只剩下(2n)条边,使得图中每个点都可以相互连通。

    知识点:  DFS

    解题思路:

      从点(1)出发,进行一次(DFS),把所有的点都访问一次,标记经过的边,这些边保证了点(1)能到所有的点。再额外建一个图(图中所有的边都是原图的边的反向),再进行一次与上面类似的DFS操作:从点(1)出发,把所有的点都访问一次,标记经过的边,这些边保证了所有的点都能到点(1)。两次(DFS)最多标记(2n-2)条边,并保证了所有点都能到点(1),点(1)能到所有点,如此所有点都能到所有点,每个点都可以相互连通。被标记的边就是必需的,删除其他边直到只剩下(2n)条边即可。

    AC代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef pair<int,int> P;
     5 const int maxn=100000+5;
     6 vector<int>G[maxn],tG[maxn];
     7 P edge[maxn];
     8 map<P,int> used;
     9 int n;
    10 bool vis[maxn];
    11 void init(){
    12     for(int i=1;i<=n;i++)   vis[i]=false;
    13 }
    14 void dfs1(int rt){
    15     for(int i=0;i<G[rt].size();i++){
    16         if(!vis[G[rt][i]]){
    17             vis[G[rt][i]]=true;
    18             dfs1(G[rt][i]);
    19             used[make_pair(rt,G[rt][i])]++;
    20         }
    21     }
    22 }
    23 void dfs2(int rt){
    24     for(int i=0;i<tG[rt].size();i++){
    25         if(!vis[tG[rt][i]]){
    26             vis[tG[rt][i]]=true;
    27             dfs2(tG[rt][i]);
    28             used[make_pair(tG[rt][i],rt)]++;
    29         }
    30     }
    31 }
    32 int main(){
    33     int t;
    34     scanf("%d",&t);
    35     while(t--){
    36         int m,u,v;
    37         scanf("%d%d",&n,&m);
    38         used.clear();
    39         for(int i=1;i<=n;i++){
    40             G[i].clear();
    41             tG[i].clear();
    42         }
    43         for(int i=1;i<=m;i++){
    44             scanf("%d%d",&u,&v);
    45             G[u].push_back(v),tG[v].push_back(u);
    46             edge[i]=make_pair(u,v);
    47         }
    48         init();
    49         vis[1]=true;
    50         dfs1(1);
    51         init();
    52         vis[1]=true;
    53         dfs2(1);
    54         int has=m;
    55         for(int i=1;i<=m&&has>2*n;i++){
    56             if(used[edge[i]]==0){
    57                 printf("%d %d
    ",edge[i].first,edge[i].second);
    58                 has--;
    59             }
    60         }
    61     }
    62     return 0;
    63 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    Exadata存储节点的CPU限制成功了没?
    如何减少Exadata计算节点CPU的Core数量
    如何选择适合你的HTAP数据库?
    小知识:Oracle中的层次查询
    小知识:使用MOS下载Oracle介质快速参考
    小知识:Flex ASM特性对集群资源显示的影响
    javaWeb request请求乱码、response响应中文乱码一站式解决方案
    java 文件File与byte[]数组相互转换的两种方式
    pr 如何调高导出视频的清晰度?
    pr 剪辑视频之剃刀用法
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/8337003.html
Copyright © 2011-2022 走看看