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\n",mx);
90     for(int i=1;i<=m;i++)
91         printf("%d %d\n",ans[i].first,ans[i].second);
92 }
Codeforces 732F

 

posted @ 2017-10-21 08:51  avancent  阅读(223)  评论(0编辑  收藏  举报