1. 程式人生 > >poj1144 tarjan求割點

poj1144 tarjan求割點

%d tchar space ems tin sdi pre digi names

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求割點