hdu 4612 warm up 无向图求割边缩点,边连通图

无向图求割边缩点,边连通图

题意:给你一个无向连通图,问加上一条边后得到的图的最少的割边数。


先求无向图的割边,然后把边连通图缩点,得到的所有缩点连成一棵树,最后就是求树上的最长路。


#pragma comment(linker,"/STACK:100000000,100000000")
#include <stdio.h>
#include <string.h>
#include <vector>
#define pb push_back

using namespace std;

const int maxn = 200002;
const int maxm = 1000002;
struct EDGE{
	int next, to, vis;
}edge[maxm*2];

struct GEEDGE {
	int u, to;
}geedge[maxm];

int head[maxn], dfn[maxn], E, time, top, low[maxn], st[maxn], belo[maxn], type, getot;

int min(int a, int b) {
	return a > b ? b : a;
}

int max(int a, int b) {
	return a > b ? a : b;
}

void init() {
	memset(head, -1, sizeof(head));
	memset(dfn, 0, sizeof(dfn));
	memset(belo, 0, sizeof(belo));
	E = top = time = type = getot = 0;
}

void newedge(int u, int to) {
	edge[E].to = to;
	edge[E].next = head[u];
	edge[E].vis = 0;
	head[u] = E++;
}
void dfs(int u) {
	low[u] = dfn[u] = ++time;
	st[++top] = u;
	for(int i = head[u];i != -1;i = edge[i].next) {
		if(edge[i].vis)	continue;
		edge[i].vis = edge[i^1].vis = 1;
		int to = edge[i].to;
		if(!dfn[to]) {
			dfs(to);
			low[u] = min(low[u], low[to]);
			if(low[to] > dfn[u]) {
				type++;
				int v;
				do {
					v = st[top--];
					belo[v] = type;
				} while(v != to);
				geedge[getot].u = u;
				geedge[getot++].to = to;
			}
		}
		else
			low[u] = min(low[u], low[to]);
	}
}

int ans;

int DFS(int u) {
	int mx = 0, tmx = 0;
	for(int i = head[u];i != -1;i = edge[i].next) {
		if(edge[i].vis)	continue;
		edge[i].vis = edge[i^1].vis = 1;
		int to = edge[i].to;
		int now = DFS(to)+1;
		if(now >= mx) {
			tmx = mx; mx = now;
		}
		else if(now > tmx)
			tmx = now;
	}
	ans = max(ans, tmx+mx);
	return mx;
}

int main() {
	int n, m, i, u, to, j;
	while(scanf("%d%d", &n, &m) != -1 && n) {
		init();
		for(i = 0;i < m; i++) {
			scanf("%d%d", &u, &to);
			newedge(u, to);
			newedge(to, u);
		}
		for(i = 1;i <= n; i++) if(!dfn[i])
			dfs(i);
		E = 0;
		memset(head, -1, sizeof(head));
		for(i = 0;i < getot; i++) {
			u = geedge[i].u;
			to = geedge[i].to;
			newedge(belo[u], belo[to]);
			newedge(belo[to], belo[u]);
		}
		ans = 0;
		DFS(0);
		printf("%d\n", getot - ans);
	}
	return 0;
}


你可能感兴趣的:(边连通图)