zoukankan      html  css  js  c++  java
  • POJ 1523 SPF (去掉割点能形成联通块的个数)

      思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数。

      注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论:

      如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边。

      代码如下:

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define maxn 1010
    struct EDGE
    {
        int to,nxt;
    } edge[maxn*10];
    int head[maxn],low[maxn],dfn[maxn],mark[maxn],vis[maxn];
    int tot,all,son,start,tail;
    void add_edge(int u,int v)
    {
        edge[tot].to = v;
        edge[tot].nxt = head[u];
        head[u] = tot++;
    }
    void init()
    {
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(mark,0,sizeof(mark));
        all = 0;
        son = 0;
    }
    void tarjan(int u,int fa)
    {
        dfn[u] = low[u] = ++all;
        for(int i = head[u]; i != -1; i = edge[i].nxt)
        {
            int v = edge[i].to;
            if(!dfn[v])
            {
                tarjan(v,u);
                low[u] = min(low[v],low[u]);
                if(low[v] >= dfn[u])
                {
                    if(u == start) son++;
                    else mark[u] = 1;
                }
            }
            else if(v != fa) low[u] = min(low[u],dfn[v]);
        }
        return ;
    }
    void bfs(int x,int cant)
    {
        queue<int>que;
        while(!que.empty()) que.pop();
        que.push(x);
        vis[x] = 1;
        while(!que.empty())
        {
            int num = que.front();
            que.pop();
            for(int i = head[num]; i != -1; i = edge[i].nxt)
            {
                int v = edge[i].to;
                if(v != cant && !vis[v])
                {
                    que.push(v);
                    vis[v] = 1;
                }
            }
        }
        return ;
    }
    int main()
    {
        int a,b;
        int ca = 0;
        while(~scanf("%d",&a))
        {
            if(!a) break;
            start = 0,tail = 0;
            scanf("%d",&b);
            start = min(a,b);
            tail = max(a,b);
            tot = 0;
            memset(head,-1,sizeof(head));
            add_edge(a,b);
            add_edge(b,a);
            while(~scanf("%d",&a))
            {
                if(!a) break;
                scanf("%d",&b);
                add_edge(a,b);
                add_edge(b,a);
                start = min(min(a,b),start);
                tail = max(max(a,b),tail);
            }
            init();
            tarjan(start,-1);
            if(son >= 2) mark[start] = 1;
            int subnets = 0,spf = 0;
            printf("Network #%d
    ",++ca);
            bool flag = true;
            for(int i = start; i <= tail; i++)
            {
                if(mark[i])
                {
                    flag = false;
                    printf("  SPF node %d leaves ",i);
                    memset(vis,0,sizeof(vis));
                    subnets = 0;
                    for(int j = start;j <= tail;j++)
                    {
                        if(j == i) continue;
                        if(!vis[j])
                        {
                            subnets++;
                            bfs(j,i);
                        }
                    }
                    printf("%d subnets
    ",subnets);
                }
            }
            if(flag) puts("  No SPF nodes");
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    MySQL涉及连接的问题
    SQL注入的问题
    如果有一个特别大的访问量到数据库上,怎么做优化?主从复制、读写分离
    MySQL,优化查询的方法
    Solr搜索引擎
    线程安全与锁优化
    Java与线程
    Java内存模型
    你不会成为数据科学家的9个原因:数据科学是一个艰难的领域,请做好准备
    深度学习中的激活函数完全指南:在数据科学的诸多曲线上进行现代之旅
  • 原文地址:https://www.cnblogs.com/jifahu/p/5515359.html
Copyright © 2011-2022 走看看