"CF 732F" tourist reform (cut edge +dfs)
Main topic:
N-point M-bar without forward edge.
Defines the number of points that Ri R_i can traverse to from point I.
It is required to determine the direction for each edge so that min (ri) min (r_i) is the largest.
Outputs the maximum min (ri) min (r_i) and the direction of each edge.
Consider the existence of a scheme for double-connected sub-graphs so that each point can traverse to all points in the graph.
Then the lock point of all double-connected (ie no-bridge) is changed into several trees.
For each point, there must be a way for the interior to reach each other. The point can be between points and only one direction is determined.
So let all the points flow to the largest point (the sub-graph with the most points before the indent)
So the answer is this diagram.
Tarjan ran out of the bridge, marked well.
Start Dfs from any point in the largest sub-graph and set the side direction.
The code is as follows:
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio > #include <climits> #include <ctime> #include <cstring> #include <queue> #include <stack&
Gt #include <list> #include <algorithm> #include <map> #include <set> #define LL Long Long #define Pr pair<int,int> #define FREAD (CH) freopen (CH, "R", stdin) #define FWRITE (CH) freopen (CH, "w", stdout) using namespace s
td
const int INF = 0X3F3F3F3F;
const int mod = 1E9+7;
Const double EPS = 1e-8;
const int MAXN = 400123;
const int MAXM = 400123;
struct Edge {int u,v,next,to;
BOOL Bridge;
} eg[maxm<<1];
BOOL VIS[MAXN],IN[MAXN],OUT[MAXN];
int BELOW[MAXN],HEAD[MAXN],DFN[MAXN],LOW[MAXN];
int tp,tim,pot,mx;
void Init () {memset (dfn,0,sizeof (DFN));
memset (In,0,sizeof (in));
Memset (out,0,sizeof (out));
memset (head,-1,sizeof (head));
TP = 0;
} void Add (int u,int v) {eg[tp].u = u; Eg[tp].v = V;
Eg[tp].next = Head[u];
Eg[tp].bridge = 0;
eg[tp].to = 0;
Head[u] = tp++;
} void Dfs (int u,int pre) {Dfn[u] = low[u] = ++tim;
printf ("%d%d%d\n", U,dfn[u],low[u]);
for (int i = head[u]; i =-1; i = eg[i].next) {int v = EG[I].V;
if (v = = pre) continue;
if (!dfn[v]) {DFS (v,u);
Low[u] = min (low[u],low[v]);
if (Low[v] > Dfn[u]) {Eg[i].bridge = Eg[i^1].bridge = 1;
}} else Low[u] = min (low[u],dfn[v]);
}} queue <int> stq;
int BFS (int u) {int cnt = 0;
Queue <int> q;
Q.push (U);
Vis[u] = 1;
while (!q.empty ()) {u = Q.front ();
Q.pop ();
cnt++;
for (int i = head[u]; i =-1; i = eg[i].next) {int v = EG[I].V;
if (Vis[v]) continue;
if (Eg[i].bridge) {Stq.push (v); ContinuE
} Vis[v] = 1;
Q.push (v);
}} return CNT;
} void Setb (int u) {vis[u] = 1;
for (int i = head[u]; i =-1; i = eg[i].next) {int v = EG[I].V;
if (eg[i].to) continue;
if (Eg[i].bridge) {eg[i].to =-1;
eg[i^1].to = 1;
} else {eg[i].to = 1;
eg[i^1].to =-1;
} if (!vis[v]) Setb (v);
} Vis[u] = 0;
} int solve (int u) {Tim = pot = mx = 0;
DFS (U,U);
memset (vis,0,sizeof (VIS));
Stq.push (U);
while (!stq.empty ()) {int tmp = BFS (Stq.front ());
if (tmp > mx) {mx = tmp;
Pot = Stq.front ();
} stq.pop ();
} memset (Vis,0,sizeof (VIS));
Setb (pot);
return MX;
} int main () {//fread ("");
Fwrite ("");
int n,m,u,v;
Init ();
scanf ("%d%d", &n,&m); for (int i = 0; i < m;++i) {scanf ("%d%d", &u,&v);
ADD (U,V);
ADD (V,u);
} printf ("%d\n", Solve (1));
for (int i = 0; i < tp; i + = 2) {if (eg[i].to = = 1) printf ("%d%d\n", EG[I].U,EG[I].V);
else printf ("%d%d\n", eg[i].v,eg[i].u);
} return 0; }