hihocoder 1183(tarjan求缩点和桥)

来源:互联网 发布:鼠标手写输入软件 编辑:程序博客网 时间:2024/06/05 15:26

题目链接:hihocoder 1183

利用tarjan模板求无向图的割点和桥。

#include<iostream>#include<stdio.h>#include<math.h>#include <string>#include<string.h>#include<map>#include<queue>#include<set>#include<utility>#include<vector>#include<algorithm>#include<stdlib.h>using namespace std;#define maxn 20005#define maxm 100005#define rd(x) scanf("%d", &x)#define rd2(x, y) scanf("%d%d", &x, &y)struct Edge{    int to,next,k;}edge[maxm *4];int head[maxn],tot;int low[maxn],dfn[maxn],Stack[maxn];int belong[maxn]; // 1~sccint Index,top;int scc; //强连通分量的个数bool instack[maxn];long long int num[maxn];int w[maxn];set<int> sset;vector< pair<int, int> > vec;void addedge(int u, int v){    edge[tot].to = v;edge[tot].next = head[u];    edge[tot].k = 1;head[u] = tot++;}void tarjan(int u, int d){    int v;    low[u] = dfn[u] = ++Index;    Stack[top++] = u;    instack[u] = true;    int son = 0;    for(int i = head[u]; i != -1; i = edge[i].next){        v = edge[i].to;        if(!edge[i].k) continue;        edge[i^1].k = 0;        if(!dfn[v]){            son++;            tarjan(v, d + 1);            if(low[u] > low[v]) low[u] = low[v];            //割边,儿子节点无法返回更早            if(low[v] > dfn[u]) vec.push_back(make_pair(min(u,v), max(u,v)));            //不是树根且儿子节点无法返回更早,即low[v] >= dfn[u],是割点            if(d != 1 && low[v] >= dfn[u]) sset.insert(u);        }        else if(instack[v] && low[u] > dfn[v]) low[u] = dfn[v];    }    //树根并且有多个子树是割点    if(son > 1 && d == 1) sset.insert(u);    if(low[u] == dfn[u]){        scc++;        do{            v = Stack[--top];            instack[v] = false;            belong[v] = scc;            //num[scc] += w[v];        }        while(v != u);    }}void solve(int N){    memset(dfn, 0, sizeof(dfn));    memset(instack, false, sizeof(instack));    memset(num, 0, sizeof(num));    Index = scc = top = 0;    for(int i = 1; i <= N; i++){        if(!dfn[i]) tarjan(i, 1);    }    //tarjan(1);}void init(){    tot = 0;    memset(head, -1, sizeof(head));}bool cmp2(pair<int, int> a, pair<int, int> b){    if(a.first == b.first) return a.second < b.second;    return a.first < b.first;}int main(){    int n, m, a, b;    init();    rd2(n, m);    for(int i =1; i <= m; i++){        rd2(a, b);        addedge(a, b);        addedge(b, a);    }    //memset(belong, 0, sizeof(belong));    solve(n);    //  重新建图    //memset(head2, -1, sizeof(head2));    //sort(sset.begin(), sset.end());    sort(vec.begin(), vec.end(), cmp2);    //printf("%lld\n",dfs(belong[1]));    if(sset.size() != 0){    for(set<int>::iterator it = sset.begin(); it != sset.end(); it ++){        if(it != sset.begin()) printf(" ");        printf("%d", *it);    }    }else printf("Null");    printf("\n");    for(vector< pair<int, int> >::iterator it = vec.begin(); it != vec.end(); it++){        printf("%d %d\n", (*it).first, (*it).second);    }    return 0;}


0 0
原创粉丝点击