zoukankan      html  css  js  c++  java
  • Codeforces 732F

    传送门

    题意:

    给出一个无向图,要求将每条边确定一个方向,使新图中所有点能到达的点的数目最小值最大。

    考虑求出边双连通分量和割边,在缩点后的图中,我们贪心的令每一条割边指向点数目最多的边双。

    对于每一个边双,我们可以用dfs确定边的方向使其在新图中变成连通分量。

    最小值为点数最多的边双的点数。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #include <math.h>
     6 using namespace std;
     7 #define maxn 400010
     8 #define pa pair<int,int>
     9 template<typename __>
    10 inline void read(__ &s)
    11 {
    12     char ch;
    13     for(ch=getchar(),s=0;ch<'0'||ch>'9';ch=getchar());
    14     for(;ch>='0'&&ch<='9';ch=getchar())
    15         s=s*10+ch-'0';
    16 }
    17 int n,m;
    18 struct edge
    19 {
    20     int v,id,nex;
    21 }e[maxn<<1];
    22 int pr[maxn],cnt;
    23 int st[maxn],top;
    24 int mx,root;
    25 int low[maxn],dfn[maxn];
    26 int bcc_dfn;
    27 pa ans[maxn];
    28 void add(int u,int v,int id)
    29 {
    30     e[++cnt]=(edge){v,id,pr[u]};
    31     pr[u]=cnt;
    32     e[++cnt]=(edge){u,id,pr[v]};
    33     pr[v]=cnt;
    34 }
    35 void tarjan(int u,int f)
    36 {
    37     low[u]=dfn[u]=++bcc_dfn;
    38     st[++top]=u;
    39     for(int i=pr[u];i;i=e[i].nex)
    40     {
    41         int v=e[i].v;
    42         if(v==f)
    43             continue;
    44         if(!dfn[v])
    45         {
    46             ans[e[i].id]=pa(v,u);
    47             tarjan(v,u);
    48             low[u]=min(low[u],low[v]);
    49         }
    50         else
    51         {
    52             ans[e[i].id]=pa(u,v);
    53             low[u]=min(low[u],dfn[v]);
    54         }
    55     }
    56     if(low[u]==dfn[u])
    57     {
    58         int siz=0;
    59         int v=-1;
    60         while(v!=u)
    61         {
    62             v=st[top--];
    63             siz++;
    64         }
    65         if(siz>mx)
    66         {
    67             mx=siz;
    68             root=u;
    69         }
    70     }
    71 }
    72 int main()
    73 {
    74     read(n);
    75     read(m);
    76     int u,v;
    77     for(int i=1;i<=m;i++)
    78     {
    79         read(u);
    80         read(v);
    81         add(u,v,i);
    82     }
    83     mx=0;
    84     tarjan(1,-1);
    85     memset(dfn,0,sizeof(dfn));
    86     bcc_dfn=0;
    87     mx=0;
    88     tarjan(root,-1);
    89     printf("%d
    ",mx);
    90     for(int i=1;i<=m;i++)
    91         printf("%d %d
    ",ans[i].first,ans[i].second);
    92 }
    Codeforces 732F
  • 相关阅读:
    BOM与DOM的区别与联系
    HTTP与HTTPS的区别
    总结一下C++与C#之间的区别
    点标记(lambda表达式+linq查询标记符)与linq语句(查询表达式)
    java多线程:继承Thread和实现Runable接口的区别
    打印BroadcastReceiver的所有接受者
    修改apk里面的源码
    关于启动模式中的问题
    onSaveInstanceState和onRestoreInstanceState()
    Options Menu的android3.0以上和以下版本显示刷新原理,刷新适配
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7703583.html
Copyright © 2011-2022 走看看