ArcTan

dfs
随笔 - 16, 文章 - 117, 评论 - 6, 引用 - 0
数据加载中……

tarjan算法-求无向连通图的关节点

无向连通图的关节点:
      1、朴素算法:枚举+DFS,O(N^3)。
      2、Robert Tarjan的Tarjan算法。O(N^2)
  Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。   定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。   当DFN(u)=Low(u)时,以u为根的搜索子树上所有节点是一个强连通分量。

SPF  POJ 1523,ZOJ 1119
只想说自己是SB啊啊啊啊:

#include<stdio.h>
#include
<string.h>
#include
<math.h>
#define min(a,b)    ((a)<(b)?(a):(b))
#define max(a,b)    ((a)>(b)?(a):(b))
#define maxn 1001
int nodes;
int tmpdfn;
int son;
int dfn[maxn];
int low[maxn];
int subnets[maxn];
bool Edge[maxn][maxn];
bool vis[maxn];
void dfs(int u)
{
    
for (int v=1;v<=nodes;v++)
    {
        
if (Edge[u][v])
        {
            
if (!vis[v])
            {
                vis[v]
=1;
                low[v]
=dfn[v]=++tmpdfn;
                dfs(v);
         
//       Edge[v][u]=Edge[u][v]=0;
                low[u]=min(low[u],low[v]);
                
if (low[v]>=dfn[u])
                {
                    
if (u!=1)
                        subnets[u]
++;
                    
else
                        son
++;
                }
            }
            
else
            {
                low[u]
=min(low[u],dfn[v]);
            }
        }
    }
}
void init()
{
    low[
1]=dfn[1]=1;
    tmpdfn
=1;
    son
=0;
    memset(vis,
0,sizeof(vis));
    vis[
1]=1;
    memset(subnets,
0,sizeof(subnets));
}
int main()
{
    
int u,v;
    
int t=0;
    
while (1)
    {
        scanf(
"%d",&u);
        
if (u==0)
            
break;
        scanf(
"%d",&v);
        nodes
=max(u,v);
        memset(Edge,
0,sizeof(Edge));
        Edge[u][v]
=Edge[v][u]=1;
        
while (1)
        {
            scanf(
"%d",&u);
            
if (u==0)
                
break;
            scanf(
"%d",&v);
            nodes
=max(nodes,u);
            nodes
=max(nodes,v);
            Edge[u][v]
=Edge[v][u]=1;
        }
        
if (t>0)    printf("\n");
        printf(
"Network #%d\n",++t);
        init();

        dfs(
1);

        
if (son>1)
            subnets[
1]=son-1;
        
bool flag=0;
        
for (int i=1;i<=nodes;i++)
        {
            
if (subnets[i]>0)
            {
                flag
=1;
                printf(
"  SPF node %d leaves %d subnets\n",i,subnets[i]+1);
            }
        }
        
if (!flag)
            printf(
"  No SPF nodes\n");
    }
    
return 0;
}

posted on 2012-07-18 21:36 wangs 阅读(799) 评论(0)  编辑 收藏 引用 所属分类: ACM-图论


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理