您的位置:首页 > 其它

POJ 1144 - Network 用tarjan求无向图的割点

2013-10-25 20:26 423 查看
题意:

给了一个无向图..问有多少个割点...

题解:

发现tarjan这一块还有一个地方没搞~~补上...

用tarjan找双联通分量...若有条边其起点的dfn不大于终点的low ..那么起点"可能"是割点...之所以说可能是因为每次dfs的第一个点必定会多一次dfn大于low的边...所以每次进入了dfs回来后要将起点的记录值-1..若其还是大于0的才说明该点是割点...

Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<set>
#include <stack>
#include<queue>
#include<algorithm>
#include<cmath>
#define oo 1000000007
#define ll long long
#define pi acos(-1.0)
#define MAXN 205
#define MAXM 50505
using namespace std; 
struct node
{
      int v,id,next; 
}edge[MAXM];
int Ne,_next[MAXN],P[MAXN],dfn[MAXN],low[MAXN],DfsIndex;
void addedge(int u,int v,int id)
{
      edge[++Ne].next=_next[u],_next[u]=Ne;
      edge[Ne].v=v,edge[Ne].id=id;
}
void tarjan(int u,int id)
{
      dfn[u]=low[u]=++DfsIndex;
      for (int k=_next[u];k;k=edge[k].next)
         if (edge[k].id!=id)
         {
                 int v=edge[k].v;
                 if (!dfn[v])
                 {
                       tarjan(v,edge[k].id);
                       low[u]=min(low[u],low[v]);
                       if (dfn[u]<=low[v]) P[u]++;
                 }else
                       low[u]=min(low[u],dfn[v]);
         }
}
int main()
{       
      int n,u,v,id,ans; 
      char c; 
      while (~scanf("%d",&n) && n)
      {
                Ne=id=0,memset(_next,0,sizeof(_next));
                while (~scanf("%d",&u) && u)
                    while (scanf("%c",&c) && c!='\n')  
                       scanf("%d",&v),addedge(u,v,++id),addedge(v,u,id); 
                memset(P,0,sizeof(P));
                memset(dfn,0,sizeof(dfn));
                DfsIndex=0;
                for (u=1;u<=n;u++)
                   if (!dfn[u])
                   {
                            tarjan(u,0);
                            P[u]--;
                   }
                ans=0;
                for (u=1;u<=n;u++) ans+=!(!P[u]);
                printf("%d\n",ans);
      }
      return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: