http://acm.hdu.edu.cn/showproblem.php?pid=4612
Test instructions
Add an edge, so that the number of bridges is minimal.
Ideas:
The edge connects the component, shrinks the point, then becomes a tree, the tree edge is the bridge, asks the tree the diameter.
The diameter of the tree is the most reduced bridge.
The minimum number of bridges is the number of bridges in the original image-the diameter of the tree.
Pay attention to the heavy edges.
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <stack> #
Include <map> using namespace std;
typedef pair<int,int> PII;
const int M_node = 200009, M_edge = 2000009;
int Low[m_node],dfn[m_node],belong[m_node],head[m_node];
int Dfs_clock,block,bridge,tot;
int n,m,maxlen,s;
BOOL Instack[m_node]; struct Node {int u,v;}
Node[m_edge];
struct Edge {int to,next;
BOOL Cut;
BOOL Mul;
}edge[m_edge];
Vector<int> G[m_node];
Stack<int> St;
void Init () {memset (head,-1,sizeof (head));
Dfs_clock = block = Bridge = tot = 0;
} void Add_edge (int u,int v,bool mul) {edge[tot].to = v;
Edge[tot].next = Head[u];
Edge[tot].cut = false;
Edge[tot].mul = Mul;
Head[u] = tot++;
} void Tarjan (int u,int fa,bool mul) {Low[u] = dfn[u] = ++dfs_clock;
St.push (U); instack[U] = true;
for (int i = head[u]; I! = -1;i = edge[i].next) {int v = edge[i].to; if (v = = FA &&!mul) continue;
If it is not a heavy edge, skip if (!dfn[v]) {Tarjan (V,u,edge[i].mul);
Low[u] = min (Low[v],low[u]);
if (Low[v] > Dfn[u]) {bridge++;
Edge[i].cut = true;
Edge[i^1].cut = true;
}} else if (Instack[u] && low[u] > Dfn[v]) low[u] = Dfn[v];
} if (low[u] = = Dfn[u]) {block++;
for (;;)
{int v = st.top ();
St.pop ();
INSTACK[V] = false;
BELONG[V] = block;
if (v = = u) break;
}}} void Dfs (int u,int pre,int len) {if (MaxLen < len) {s = u;
MaxLen = Len;
} for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];
if (v = = pre) continue;
DFS (V,U,LEN+1); }} VoiD solve () {while (!st.empty ()) St.pop ();
memset (dfn,0,sizeof (DFN));
memset (instack,false,sizeof (instack));
Tarjan (1,-1,false);
for (int i = 1;i <= block;i++) g[i].clear (); for (int i = 1;i <= n;i++) {for (int j = head[i];j! = -1;j = Edge[j].next) {if (Edge[j]. Cut) {//printf ("debug--i =%d, belong[i] =%d, edge[j].to =%d, belong[edge[j].to] =%d\
N ", i,belong[i],edge[j].to,belong[edge[j].to]);
G[belong[i]].push_back (belong[edge[j].to]);
}}} MaxLen =-1;
DFS (1,-1,0);
MaxLen =-1;
DFS (s,-1,0);
printf ("%d\n", Bridge-maxlen);
} BOOL CMP (Node A,node b) {if (a.u = = b.u) return A.V < B.V;
return a.u < b.u;
} int main () {while (scanf ("%d%d", &n,&m) = = 2) {init ();
if (n = = 0 && m = = 0) break;
for (int i = 0;i < m;i++) {int A, B; scanf ("%d%d",&A,&B);
if (a = = B) Continue;
if (a > B) swap (b);
NODE[I].U = A;
NODE[I].V = b;
} sort (node,node+m,cmp); for (int i = 0;i < m;i++) {if (i = = 0 | |
(node[i].u! = NODE[I-1].U | | node[i].v! = NODE[I-1].V))
{if (i < m-1 && node[i].u = = node[i+1].u && node[i].v = = node[i+1].v)
{Add_edge (node[i].u,node[i].v,true);
Add_edge (node[i].v,node[i].u,true);
} else {Add_edge (node[i].u,node[i].v,false);
Add_edge (Node[i].v,node[i].u,false);
}}} solve ();
} return 0;
}