HDOJ-3849(无向图桥)

来源:互联网 发布:阿里云 流量收费标准 编辑:程序博客网 时间:2024/04/30 06:11

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3849

同割顶类似,对于顶点u,如果其存在孩子节点v,使得v及其子孙不存在指向u或者u祖先的边,则(u,v)是一座桥:


#include <cstdio>#include <cstring>#include <map>#include <vector>#include <algorithm>using namespace std;#define MAX_N   10000#define MAX_M   100000//structureint N, M, nextId, dfsClock, pre[MAX_N];struct Edge{    int l, r;} edges[MAX_M];vector<int> bridge;//relationvector<int> relation[MAX_N];//namechar name[MAX_N + 5][16];int index;inline char* getString(){ return name[index++]; }//name->idmap<int,char*> idNameMap;inline char* getNameById(int i){ return idNameMap[i]; }//id->namestruct Comparator{    bool operator () (char* a, char* b){        return strcmp(a, b) < 0;    }};typedef map<char*,int,Comparator> Map;Map nameIdMap;Map::iterator iter;bool getIdByName(int& id, char* s, int& nextId){    iter = nameIdMap.find(s);    if(iter == nameIdMap.end()){        id = nextId++;        nameIdMap.insert(Map::value_type(s, id));        idNameMap.insert(map<int,char*>::value_type(id, s));        return false;    }    id = iter->second;    return true;}int dfs(int x, int fa){    int lowx, y, lowy, a, b;    const vector<int>& v = relation[x];        lowx = pre[x] = ++dfsClock;    for(int i = 0, n = v.size(); i < n; ++i){        a = edges[v[i]].l;        b = edges[v[i]].r;        if(a == x) y = b;        else y = a;        if(pre[y]){            if(y != fa) lowx = min(lowx, pre[y]);        }        else{            lowy = dfs(y, x);            if(lowy > pre[x]) bridge.push_back(v[i]);            lowx = min(lowx, lowy);        }    }    return lowx;}void solve(){    dfsClock = 0;    bridge.clear();    for(int i = 0; i < nextId; ++i){        if(!pre[i]) dfs(i, -1);    }    for(int i = 0; i < N; ++i){        if(!pre[i]){            puts("0");            return;        }    }    printf("%u\n", bridge.size());    sort(bridge.begin(), bridge.end());    for(int i = 0, n = bridge.size(); i < n; ++i){        printf("%s %s\n", getNameById(edges[bridge[i]].l),                           getNameById(edges[bridge[i]].r)        );    }}void prepare(){    scanf("%d%d", &N, &M);    index = nextId = 0;    idNameMap.clear();    nameIdMap.clear();    for(int i = 0; i < N; ++i){        relation[i].clear();        pre[i] = 0;    }    if(M == 0) return;    char* s = getString(), *t = getString();    int x, y;    for(int i = 0; i < M; ++i){        scanf(" %s %s", s, t);        if(!getIdByName(x, s, nextId)) s = getString();        if(!getIdByName(y, t, nextId)) t = getString();        edges[i].l = x;        edges[i].r = y;        relation[x].push_back(i);        relation[y].push_back(i);    }}int main(){    int test;    for(scanf("%d", &test); test--; ){        prepare();        solve();    }    return 0;}

0 0