• UVA 10972


    UVA 10972 - RevolC FaeLoN

    题目链接

    题意:给定一个无向图(不一定全连通)。如今把边定向,问还要加入几条边使得图强连通

    思路:先求出边-双连通分量,每一个连通分量都能定向,然后缩点。转化为欧拉回路,假设每一个点度数都是大于等于2的偶数就是回路,也就是强连通了,所以计算度数为0和1的个数。一条边能添加两个度数。所以答案为所以仅仅要再加入上(a + 1) / 2 + b条边就能够了。注意特判一開始就已经是边-双连通分量的情况。答案应该为0

    代码:

    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int N = 1005;
    
    struct Edge {
    	int u, v, id;
    	int fan;
    	bool iscut, used;
    	Edge() {}
    	Edge(int u, int v, int id, int fan) {
    		this->u = u;
    		this->v = v;
    		this->id = id;
    		this->fan = fan;
    		used = false;
    		iscut = false;
    	}
    };
    
    int pre[N], low[N], dfs_clock;
    
    vector<Edge> g[N];
    vector<Edge> cut;
    
    int dfs(int u, int fa) {
    	int lowu = pre[u] = ++dfs_clock;
    	for (int i = 0; i < g[u].size(); i++) {
    		int v = g[u][i].v;
    		int id = g[u][i].id;
    		if (id == fa) continue;
    		if (!pre[v]) {
    			int lowv = dfs(v, id);
    			lowu = min(lowu, lowv);
    			if (lowv > pre[u]) {
    				cut.push_back(g[u][i]);
    				g[u][i].iscut = true;
    				g[v][g[u][i].fan].iscut = true;
    			}
    		} else lowu = min(lowu, pre[v]);
    	}
    	return low[u] = lowu;
    }
    
    int bcc_cnt, bccno[N];
    
    void dfs2(int u, int bcc_cnt) {
    	bccno[u] = bcc_cnt;
    	for (int i = 0; i < g[u].size(); i++) {
    		if (g[u][i].iscut) continue;
    		int v = g[u][i].v;
    		if (bccno[u] == bccno[v]) continue;
    		dfs2(v, bcc_cnt);
    	}
    }
    
    void find_cut(int n) {
    	cut.clear();
    	memset(pre, 0, sizeof(pre));
    	dfs_clock = 0;
    	for (int i = 0; i < n; i++) {
    		if (!pre[i]) {
    			dfs(i, 0);
    		}
    	}
    }
    
    void find_bcc(int n) {
    	find_cut(n);
    	bcc_cnt = 0;
    	memset(bccno, 0, sizeof(bccno));
    	for (int i = 0; i < n; i++) {
    		if (bccno[i]) continue;
    		dfs2(i, ++bcc_cnt);
    	}
    }
    
    int n, m, du[N];
    
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		for (int i = 0; i < n; i++) g[i].clear();
    		int u, v;
    		for (int i = 1; i <= m; i++) {
    			scanf("%d%d", &u, &v);
    			u--; v--;
    			g[u].push_back(Edge(u, v, i, g[v].size()));
    			g[v].push_back(Edge(v, u, i, g[u].size() - 1));
    		}
    		find_bcc(n);
    		if (bcc_cnt == 1) {
    			printf("0
    ");
    			continue;
    		}
    		memset(du, 0, sizeof(du));
    		for (int i = 0; i < cut.size(); i++) {
    			int u = cut[i].u, v = cut[i].v;
    			if (bccno[u] != bccno[v]) {
    				du[bccno[u]]++; du[bccno[v]]++;
    			}
    		}
    		int a = 0, b = 0;
    		for (int i = 1; i <= bcc_cnt; i++) {
    			if (du[i] == 1) a++;
    			if (du[i] == 0) b++;
    		}
    		printf("%d
    ", (a + 1) / 2 + b);
    	}
    	return 0;
    }


  • 相关阅读:
    在多线程中使用静态方法是否有线程安全问题(转载)
    为什么乐观的人多能成功呢?
    每个人都是超级英雄-《技巧:如何用一年的时间获得十年的经验》
    003|再谈10000小时,三板斧破四困境
    002|也谈10000小时
    在职场中如何通过讲故事,影响他人、支持自己(下篇)
    全面解读:微信服务号升级和群发增至4条的应用方法
    Technical reading July-15
    read links July-14
    Technical news July-11
  • 原文地址:https://www.cnblogs.com/llguanli/p/6747037.html
Copyright © 2020-2023  润新知