732F Tourist Reform

 1 // CF 732F Tourist Reform
 2 // 思路:两遍tarjan
 3 // 找强联通分量
 4 #include <bits/stdc++.h>
 5 using namespace std;
 6 #define LL long long
 7 typedef pair<int,int> pii;
 8 const int inf = 0x3f3f3f3f;
 9 const int N =41e5+10;
10 #define clc(a,b) memset(a,b,sizeof(a))
11 const double eps = 1e-8;
12 const int MOD = 1e9+7;
13 void fre() {freopen("in.txt","r",stdin);}
14 void freout() {freopen("out.txt","w",stdout);}
15 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
16 
17 int head[N],low[N],dfn[N],s[N];
18 int cnt,tot;
19 struct Edge{
20     int v,w,nt;
21     Edge(){}
22     Edge(int v_,int w_,int nt_):v(v_),w(w_),nt(nt_){}
23 }e[N<<1];
24 
25 void add(int u,int v,int w){
26     e[cnt]=Edge(v,w,head[u]);
27     head[u]=cnt++;
28 }
29 pii mat[N];
30 int rt;
31 int ans;
32 void tarjan(int u,int f){
33     low[u] = dfn[u] = ++ tot;
34     s[++s[0]] = u;
35     for(int i = head[u]; i != -1; i = e[i].nt) {
36         int v = e[i].v;
37         if(v == f) continue;
38         if(!dfn[v]) {
39             mat[e[i].w] = make_pair(v, u);
40             tarjan(v, u);
41             low[u] = min(low[u], low[v]);
42         }
43         else {
44             mat[e[i].w] = make_pair(u, v);
45             low[u] = min(low[u], dfn[v]);
46         }
47     }
48     if(dfn[u] == low[u]) {
49         int res = 1;
50         while(s[s[0]] != u) {
51             ++ res;
52             -- s[0];
53         }
54         -- s[0];
55         if(ans < res) {ans = res; rt = u;}
56     }
57 }
58 
59 void init(){
60     clc(head,-1);
61     tot=0;
62     cnt=0;
63     ans=0;
64 }
65 int main(){
66     init();
67     int n,m;
68     scanf("%d%d",&n,&m);
69     for(int i=1;i<=m;i++){
70         int u,v;
71         scanf("%d%d",&u,&v);
72         add(u,v,i);
73         add(v,u,i);
74     }
75     s[0]=0;
76     tarjan(1,-1);
77     clc(dfn,0);
78     tot=0;
79     s[0]=0;
80     tarjan(rt,-1);
81     printf("%d
",ans);
82     for(int i=1;i<=m;i++){
83         printf("%d %d
",mat[i].first,mat[i].second);
84     }
85     return 0;
86 }
原文地址:https://www.cnblogs.com/ITUPC/p/5982217.html