• codeforces 732F


    这题是要求给无向图定向之后最大化每个点能到达的点的个数的最小值

    显然定向后如果一些点构成SCC那么是可以互达的,而满足这个条件的点在原图上是个BCC(边双)

    简单证明一下这个结论:

    一方面,如果存在桥边,那么显然桥边在缩点后会变成一个单向边,两边没法互达;

    另一方面,如果一些点构成了BCC,那么根据tarjan算法,只需要把树边向下定向,返祖边向上定向,那么一定可以从根走到叶子再回到根,这显然是个SCC

    那么我们跑一遍BCC的tarjan缩点,之后形成了一棵树(树边是桥边)

    树的话,可以发现有一个点一定没有出度,如果这个点不是BCC内点数最多的点那么显然不是最小

    所以我们把BCC内点数最多的点定为根,其他指向根就行了

    复杂度(O(n+m))

     1 #include<bits/stdc++.h>
     2 #define maxn 400005
     3 using namespace std;
     4 int n,m;
     5 vector< pair<int,int> > g[maxn],Ans,g2[maxn];
     6 vector<int> bcc[maxn];
     7 int pre[maxn],low[maxn],Tim,cnt,isbri[maxn],bel[maxn];
     8 stack<int> stk;
     9 void tarjan(int u,int fid)
    10 {
    11     pre[u]=low[u]=++Tim;
    12     stk.push(u);
    13     for(auto pa:g[u])
    14     {
    15         int v=pa.first,nid=pa.second;
    16         if(nid==fid)continue;
    17         if(!pre[v])
    18         {
    19             tarjan(v,nid);
    20             low[u]=min(low[u],low[v]);
    21             if(pre[u]<low[v])isbri[nid]=1;
    22             else
    23             {
    24                 if(Ans[nid].first==v)swap(Ans[nid].first,Ans[nid].second);
    25             }
    26         }
    27         else
    28         {
    29             if(pre[v]<pre[u])low[u]=min(low[u],pre[v]);
    30             if(Ans[nid].first==u)swap(Ans[nid].first,Ans[nid].second);
    31         }
    32     }
    33     if(low[u]==pre[u])
    34     {
    35         ++cnt;
    36         while(1)
    37         {
    38             int x=stk.top();stk.pop();
    39             bcc[cnt].push_back(x);
    40             bel[x]=cnt;
    41             if(x==u)break;
    42         }
    43     }
    44 }
    45 void dfs(int u,int fa)
    46 {
    47     for(auto pa:g2[u])
    48     {
    49         int v=pa.first,nid=pa.second;
    50         if(v==fa)continue;
    51         if(bel[Ans[nid].first]==u)swap(Ans[nid].first,Ans[nid].second);
    52         dfs(v,u);
    53     }
    54 }
    55 int main()
    56 {
    57     scanf("%d%d",&n,&m);
    58     Ans.resize(m+2);
    59     for(int u,v,i=1;i<=m;++i)
    60     {
    61         scanf("%d%d",&u,&v);
    62         g[u].push_back(make_pair(v,i));
    63         g[v].push_back(make_pair(u,i));
    64         Ans[i]=make_pair(u,v);
    65     }
    66     Tim=0;
    67     tarjan(1,0);
    68     int rt=0;
    69     for(int i=1;i<=cnt;++i)if(bcc[i].size()>bcc[rt].size())rt=i;
    70     printf("%d
    ",bcc[rt].size());
    71     for(int u=1;u<=n;++u)
    72     {
    73         for(auto pa:g[u])
    74         {
    75             int v=pa.first,nid=pa.second;
    76             if(isbri[nid])g2[bel[u]].push_back(make_pair(bel[v],nid));
    77         }
    78     }
    79     dfs(rt,0);
    80     for(int i=1;i<=m;++i)printf("%d %d
    ",Ans[i].first,Ans[i].second);
    81 }
    View Code
  • 相关阅读:
    001-nginx基础配置-location、Rewrite、return 直接返回码、全局变量
    001-Spring Cloud Edgware.SR3 升级最新 Finchley.SR1,spring boot 1.5.9.RELEASE 升级2.0.4.RELEASE注意问题点
    004-读书记录
    007-ant design 对象属性赋值,双向绑定
    006-ant design -结合echart-地址map市
    005-ant design -结合echart
    002-Spring Framework-Core-01-IoC容器
    003-驾照考试,总结
    006-markdown基础语法
    java-mybaits-010-mybatis-spring-使用 SqlSession、注入映射器
  • 原文地址:https://www.cnblogs.com/uuzlove/p/12298077.html
Copyright © 2020-2023  润新知