zoukankan      html  css  js  c++  java
  • Bridges painting

    题目大意:有个一无向图,给所有的边染色,如果一个点连接的边超过两个,那么最少要染一个白色和一个黑色,能否给整个图染色?不能输出“No solution”。

    分析:引用连接 http://edward-mj.com/archives/445

    首先构建dfs树,无向图dfs树具有的一大优点是该点只会向自己的祖先或子孙有非树边。

    然后按深度交替染色。返祖边与自己的儿子涂同样的颜色。

    如果dfs树中根结点度超过1,那么就找一条边染不同的颜色。

    否则看根结点是否满足条件,如果不是,那么找一个与根结点相连的叶子,向上找到一个度大于2的点为止,将该路径上所以边反色,并且将根与该叶子的边反色。如果找不到度大于2的点,那么是奇环,无解。

    ps.注意这组数据:

    5
    2 3 0
    1 3 0
    1 2 4 5 0
    3 5 0
    3 4 0

    代码如下:

    ======================================================================================================================

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    const int MAXN = 107;
    
    int c[MAXN][MAXN], N;///保存边的颜色, N个点
    int father[MAXN], nSon[MAXN];
    vector<int> e[MAXN];///相连接的点
    
    void DFS(int u, int color)
    {
        for(int i=0; i<e[u].size(); i++)
        {
            if(c[u][e[u][i]] != -1)
                continue;///这条边已经被访问过
    
            nSon[u]++;///子树数目加1
            c[e[u][i]][u] = c[u][e[u][i]] = color;
    
            if(!nSon[e[u][i]])
            {///如果不是连接的祖边
                father[e[u][i]] = u;
                DFS(e[u][i], color^1);
            }
        }
    }
    
    int main()
    {
        int i, j, x;
    
        scanf("%d", &N);
    
        for(i=1; i<=N; i++)
        {
            while(scanf("%d", &x), x)
                e[i].push_back(x);
        }
    
        memset(c, -1, sizeof(c));
    
        for(i=1; i<=N; i++)
        {
            if(nSon[i] || father[i] || e[i].size()==0)
                continue;
    
            ///没有父节点,也没有儿子节点,说明未被访问过
            for(j=0; j<e[i].size(); j++)
            {///与根节点连接的第一个节点赋值为颜色0,后面的赋值为别的颜色
                if(j==0)
                {
                    nSon[i]++, father[e[i][j]] = i;
                    c[i][e[i][j]] = c[e[i][j]][i] = 0;
                    DFS(e[i][j], 1);
                }
                else if(c[i][e[i][j]] == -1)
                {///这条边未被访问过
                    nSon[i]++, father[e[i][j]] = i;
                    c[i][e[i][j]] = c[e[i][j]][i] = 1;
                    DFS(e[i][j], 0);
                }
            }
    
            if(nSon[i] >= 2 || e[i].size() == 1)
                continue;
            ///如果根节点的子树数目小于2,或者只有一个子节点
    
            for(j=1; j<e[i].size(); j++)
            {///从子节点往父节点查找一个节点有大于或等于两个子树的节点
                ///如果找到那么就把这条路径上的所有边取反,如果找不到,无解
    
                x = e[i][j];
    
                if(c[x][i] == 1)
                    break;///不需要取反也可以
    
                while(father[x] != i && nSon[x] < 2)
                    x = father[x];
    
                if(father[x] == i)
                    continue;///未找到这样的节点
    
                x = e[i][j];
                c[x][i] = c[i][x] = 1;
                while(nSon[x] < 2)
                {///路径上的边取反
                    c[x][father[x]] = c[father[x]][x] = c[x][father[x]] ^ 1;
                    x = father[x];
                }
    
                break;
            }
    
            if(j == e[i].size())
                break;///无解
        }
    
        if(i <= N)
            printf("No solution
    ");
        else
        {
            for(i=1; i<=N; i++)
            {
                for(j=0; j<e[i].size(); j++)
                    printf("%d ", c[i][e[i][j]]+1);
                printf("0
    ");
            }
        }
    
        return 0;
    }
    /**
    5
    2 3 0
    1 3 0
    1 2 4 5 0
    3 5 0
    3 4 0
    **/
  • 相关阅读:
    iaf——接口自动化测试框架
    性能优化系列
    MVC架构简介及其测试策略
    10种常见的软件架构模式
    软件开发框架分析和架构模式
    安全测试基础&安全测试---AppScan扫描工具
    WEB安全测试要点总结
    大数据Hadoop Hive HBase Spark Storm
    第三方授权方式1
    java-weixin-tools接入微信
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4834535.html
Copyright © 2011-2022 走看看