Test instructions: Known undirected graph, ask to add the least edge to make it a side double connected graph
Idea: It is obvious to indent the point into a tree, add the least side to make the edge of a tree connected
Here is the conclusion: for a tree to add (1+leaf) >>1 strip without the edge can be structured into a double-connected graph, the construction method is obvious (brain repair
216K 63MS C + + 1754B #include <cstdio> #include <iostream> #include <cstring> #include
<algorithm> using namespace std;
const int N = 1010;
struct node {int v,next;
}es[n*n];
int head[n];
int n,m;
int low[n],dfn[n],index;
int indeg[n];
void Ini () {memset (head,-1,sizeof (head));
memset (dfn,0,sizeof (DFN));
index=0;
memset (indeg,0,sizeof (indeg));
} void Tarjan (int u,int pa) {dfn[u]=low[u]=++index;
for (int i=head[u];~i;i=es[i].next) {int v=es[i].v;
if (dfn[v]==0) {Tarjan (v,u);
Low[u]=min (Low[u],low[v]);
} if (V!=PA) low[u]=min (Low[u],low[v]);
}} int main () {while (~scanf ("%d%d", &n,&m)) {ini ();
for (int i=1;i<=m;i++) {int u,v; scanf ("%d%d", &u,&v);
Es[i].v=v;
Es[i].next=head[u];
Head[u]=i;
Es[i+m].v=u;
ES[I+M].NEXT=HEAD[V];
Head[v]=i+m;
} for (int i=1;i<=n;i++) if (dfn[i]==0) Tarjan (i,-1);
for (int u=1;u<=n;u++) {for (int i=head[u];~i;i=es[i].next) {
int v= es[i].v;
if (Low[v]==low[u]) continue;
indeg[low[u]]++;
}} int leaf=0;
for (int i=1;i<=n;i++) if (indeg[i]==1) leaf++;
printf ("%d\n", (leaf+1)/2);
} return 0;
}
The above code is a self-adaptation of a Tarjan, only in this problem can be used, has not proved a clear error, the following is the positive solution:
#include <cstdio> #include <cstring> #include <iostream> #include <cstring> using namespace std;
int n,m;
const int N = 1000+100;
const int M = 2*n;
int head[n],cnt; struct Edge {int v,nxt;}
ES[M];
inline void Add_edge (int u,int v) {es[cnt].v=v;
Es[cnt].nxt=head[u];
head[u]=cnt++;
Es[cnt].v=u;
ES[CNT].NXT=HEAD[V];
head[v]=cnt++;
} typedef pair<int,int>pii;
PII Bridge[m];
int dfn[n],sta[n],top,scc,index,col[n],low[n],cbr;
void Tarjan (int u,int pa) {dfn[u]=low[u]=++index;
Sta[++top]=u;
for (int i=head[u];~i;i=es[i].nxt) {int v=es[i].v;
if (V==PA) continue;
if (dfn[v]==0) {Tarjan (v,u);
Low[u]=min (Low[u],low[v]);
if (Low[v]>dfn[u]) {scc++;
int VV;
do {vv=sta[top--];
COL[VV]=SCC;
}while (VV!=V); bridge[++cbr]=pii (U,V);
}} else Low[u]=min (Low[u],dfn[v]);
}} int in[n];
void Ini () {memset (dfn,0,sizeof (DFN));
memset (col,0,sizeof (col));
memset (In,0,sizeof (in));
memset (head,-1,sizeof (head));
top=scc=cbr=index=cnt=0;
} int main () {while (~scanf ("%d%d", &n,&m)) {ini ();
for (int i=1;i<=m;i++) {int u,v;
scanf ("%d%d", &u,&v);
Add_edge (U,V);
} for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan (i,-1);
if (top) scc++;
while (top) {COL[STA[TOP--]]=SCC;
} for (int i=1;i<=cbr;i++) {int u=bridge[i].first,v=bridge[i].second;
in[col[u]]++;
in[col[v]]++;
} int leaf=0;
for (int i=1;i<=scc;i++) if (in[i]==1) leaf++;
printf ("%d\n", (leaf+1) >>1);
} return 0;
}