zoukankan      html  css  js  c++  java
  • HDU 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通)

    HDU 3849 By Recognizing These Guys, We Find Social Networks Useful

    题目链接

    题意:说白了就是求一个无向图的桥

    思路:字符串hash掉,然后双连通。要注意特判一下假设不是一个连通块。那么答案是0

    代码:

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    using namespace std;
    
    const int N = 10005;
    const int M = 200005;
    int t, n, m;
    map<string, int> hash;
    char A[20], B[20];
    
    struct Edge {
    	int u, v, id;
    	bool iscut;
    	Edge() {}
    	Edge(int u, int v, int id) {
    		this->u = u;
    		this->v = v;
    		this->id = id;
    		this->iscut = false;
    	}
    } edge[M];
    
    int en, first[N], next[M], hn;
    char name[N][20];
    
    void init() {
    	en = hn = 0;
    	memset(first, -1, sizeof(first));
    	hash.clear();
    }
    
    int get(char *str) {
    	if (!hash.count(str)) {
    		strcpy(name[hn], str);
    		hash[str] = hn++;
    	}
    	return hash[str];
    }
    
    void add_edge(int u, int v, int id) {
    	edge[en] = Edge(u, v, id);
    	next[en] = first[u];
    	first[u] = en++;
    }
    
    int pre[N], dfn[N], dfs_clock, ans = 0;
    
    void dfs_cut(int u, int f) {
    	pre[u] = dfn[u] = ++dfs_clock;
    	for (int i = first[u]; i + 1; i = next[i]) {
    	if (edge[i].id == f) continue;
    		int v = edge[i].v;
    		if (!pre[v]) {
    			dfs_cut(v, edge[i].id);
    			dfn[u] = min(dfn[u], dfn[v]);
    			if (dfn[v] > pre[u]) {
    				ans++;
    				edge[i].iscut = edge[i^1].iscut = true;
    			}
    		} else dfn[u] = min(dfn[u], pre[v]);
    	}
    }
    
    void find_cut() {
    	memset(pre, 0, sizeof(pre));
    	for (int i = 0; i < n; i++)
    		if (!pre[i]) dfs_cut(i, -1);
    }
    
    int parent[N];
    
    int find(int x) {
    	return parent[x] == x ?

    x : parent[x] = find(parent[x]); } int main() { scanf("%d", &t); while (t--) { init(); scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) parent[i] = i; int cnt = n; for (int i = 0; i < m; i++) { scanf("%s%s", A, B); int u = get(A), v = get(B); add_edge(u, v, i); add_edge(v, u, i); int pu = find(u), pv = find(v); if (pu != pv) { cnt--; parent[pu] = pv; } } if (cnt > 1) { printf("0 "); continue; } ans = 0; find_cut(); printf("%d ", ans); for (int i = 0; i < en; i += 2) if (edge[i].iscut) printf("%s %s ", name[edge[i].u], name[edge[i].v]); } return 0; }



  • 相关阅读:
    装饰器的理解和使用
    策略模式的理解
    mongo 多条件or
    不止代码 == 摘读
    egret打包android + android微信登录--小结
    springboot整合mongo多数据源
    SpringBoot集成JWT 实现接口权限认证
    nginx反向代理使用网址速度变慢
    2017年2月总结
    (转)Mac os x 下配置Intellij IDEA + Tomcat 出现权限问题的解决办法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6714137.html
Copyright © 2011-2022 走看看