码迷,mamicode.com
首页 > 其他好文 > 详细

poj1144 tarjan求割点

时间:2017-12-05 00:56:46      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:tin   ==   etl   算法   main   poj   oid   str   strlen   

poj1144 tarjan求割点

额,算法没什么好说的,只是这道题的读入非常恶心。

还有,理解tarjan一定要用递归树,配合横边回边前边树边等来想。。

#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=100, maxm=5000;

struct Graph{
    struct Edge{
        int to, next; Graph *bel;
        inline int operator *(){ return to; }
        Edge& operator ++(){
            return *this=bel->edge[next]; }
    };
    void addedge(int x, int y){
        Edge &e=edge[++cntedge];
        e.to=y; e.next=fir[x];
        fir[x]=cntedge; e.bel=this;
    }
    void reset(){
        cntedge=0; memset(fir, 0, sizeof(fir)); }
    Edge& getlink(int x){
        return edge[fir[x]]; }
    Edge edge[maxm*2];
    int cntedge, fir[maxn];
}g;

int n, x, y, len, cut[maxn];
int time, dfn[maxn], low[maxn];
char s[maxn*5];

int getint(){
    char c; int flag=1, re=0;
    for (c=getchar(); !isdigit(c); c=getchar())
        if (c=='-') flag=-1;;
    for (re=c-48; c=getchar(), isdigit(c); re=re*10+c-48);
    return re*flag;
}

void tarjan(int now){
    dfn[now]=low[now]=++time;
    int cntc=0; Graph::Edge e=g.getlink(now);
    for (; *e; ++e){
        if (dfn[*e]) low[now]=min(low[now], dfn[*e]);
        else{
            ++cntc; //这里错了一次
            tarjan(*e);
            low[now]=min(low[now], low[*e]);
            if (low[*e]>=dfn[now]) cut[now]=1;
        }
    }
    if (now==1) cut[now]=cntc>1?1:0;
}

int main(){
    while (n=getint()){
        g.reset();
        while (x=getint()){
            fgets(s, maxn*5, stdin);
            len=strlen(s); y=0;
            for (int i=0; i<=len; ++i){
                if (!isdigit(s[i])&&y){
                    g.addedge(x, y); g.addedge(y, x);
                    y=0; }
                if (isdigit(s[i])) y=y*10+s[i]-48;
            }
        }
        for (int i=1; i<=n; ++i)
            dfn[i]=low[i]=cut[i]=0;
        time=0; tarjan(1); int cnt=0;
        for (int i=1; i<=n; ++i) if (cut[i]) ++cnt;
        printf("%d\n", cnt);
    }
    return 0;
}

poj1144 tarjan求割点

标签:tin   ==   etl   算法   main   poj   oid   str   strlen   

原文地址:http://www.cnblogs.com/MyNameIsPc/p/7979697.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!