要使游客不受道路施工的影响,能够到达各个景点,那么就要使图是至少一个双连通分量,因为
施工时只对一道路施工。
这样模型就建立了: 给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图。
同样用tarjan缩点,然后求出缩点树的叶子结点个数,再按照公式计算。
/*Accepted 220K 0MS C++ 1783B 2012-07-30 09:53:31*/ #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int MAXN = 1 << 10; const int MAXR = 1 << 11; int low[MAXN], first[MAXN], next[MAXR], v[MAXR], s[MAXN], color[MAXN]; int dfn[MAXN], N, R, e, top, cnt, col, dgr[MAXN], ans; void addedge(int x, int y) { v[e] = y; next[e] = first[x], first[x] = e ++; } void tarjan(int cur, int p) { int i; low[cur] = dfn[cur] = ++ cnt; s[top ++] = cur; for(i = first[cur]; i != -1; i = next[i]) { if(v[i] != p) { if(!dfn[v[i]]) { tarjan(v[i], cur); if(low[v[i]] < low[cur]) low[cur] = low[v[i]]; } else if(dfn[v[i]] < low[cur]) low[cur] = dfn[v[i]]; } } if(low[cur] == dfn[cur]) { ++ col; for(s[top] = -1; s[top] != cur; ) color[s[-- top]] = col; } } void cal() { int i, j, k; ans = 0; col = cnt = top = 0; memset(dfn, 0, sizeof dfn); tarjan(1, -1); memset(dgr, 0, sizeof dgr); for(i = 1; i <= N; i ++) for(j = first[i]; j != -1; j = next[j]) if(color[i] != color[v[j]]) ++ dgr[color[i]], ++ dgr[color[v[j]]]; for(i = 1; i <= col; i ++) if(dgr[i] == 2) ++ ans; ans = (ans + 1) / 2; } void ReadGraph() { int i, x, y; memset(first, -1, sizeof first); e = 0; for(i = 0; i < R; i ++) { scanf("%d%d", &x, &y); addedge(x, y), addedge(y, x); } } int main() { while(scanf("%d%d", &N, &R) == 2) { ReadGraph(); cal(); printf("%d\n", ans); } }