• POJ 3177 Redundant Paths


    边双连通分量+缩点

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 10000 + 10; 
    const int Maxn = 2 * 100000 + 10; 
    int low[maxn];
    int dfn[maxn];
    int U[maxn], V[maxn];
    int flag[maxn];
    struct Edge
    {
        int from, to, id, ans;
    } edge[Maxn];
    vector<int>G[maxn];
    int N, M;
    int tmpdfn;
    int tot;
    int Start, End;
    int TxT[maxn];
    int Belong[maxn];
    int Block;
    int SUM[maxn];
    
    void init()
    {
        for (int i = 0; i<maxn; i++) G[i].clear();
        memset(low, 0, sizeof(low));
        memset(dfn, 0, sizeof(dfn));
        memset(flag, 0, sizeof(flag));
        memset(TxT, 0, sizeof(TxT));
        memset(SUM, 0, sizeof SUM);
        memset(Belong, 0, sizeof Belong);
        low[1] = dfn[1] = 1;
        tmpdfn = 0;
        tot = 0;
        Block = 0;
    }
    
    void AddEdge(int u, int v)
    {
        edge[tot].from = u;
        edge[tot].to = v;
        edge[tot].id = tot;
        edge[tot].ans = 0;
        G[u].push_back(tot);
        tot++;
    
        edge[tot].from = v;
        edge[tot].to = u;
        edge[tot].id = tot;
        edge[tot].ans = 0;
        G[v].push_back(tot);
        tot++;
    }
    
    int Tarjan(int u, int id)
    {
        tmpdfn++;
        int lowu = dfn[u] = tmpdfn;
        for (int i = 0; i<G[u].size(); i++)
        {
            int B = G[u][i];
            if (!dfn[edge[B].to])
            {
                int lowv = Tarjan(edge[B].to, edge[B].id);
                lowu = min(lowu, lowv);
                if (lowv >= dfn[u])
                {
                    if (lowv>dfn[u])
                        edge[B].ans = 1;
                }
            }
            else if (dfn[edge[B].to])
            {
                if (edge[B].id / 2 == id / 2) continue;
                lowu = min(lowu, dfn[edge[B].to]);
            }
        }
        low[u] = lowu;
        return lowu;
    }
    
    void Dfs(int x, int y)
    {
        int XZ = 0;
        for (int i = 0; i<G[x].size(); i++)
        {
            int B = G[x][i];
            if (!flag[edge[B].id / 2])
            {
                XZ = 1;
                flag[edge[B].id / 2] = 1;
                TxT[edge[B].to] = 1;
                Belong[edge[B].from] = Block;
                Belong[edge[B].to] = Block;
                Dfs(edge[B].to, y + 1);
            }
        }
        if (!XZ&&!y) Belong[x] = Block;
    }
    
    void Slove()
    {
        for (int i = 0; i<2 * M; i++)
        if (edge[i].ans)
            flag[edge[i].id / 2] = 1;
    
        for (int i = Start; i <= End; i++)
        {
            if (!TxT[i])
            {
                TxT[i] = 1;
                Block++;
                Dfs(i, 0);    
            }
        }
    }
    
    int main()
    {
        while (~scanf("%d%d", &N, &M))
        {
            init();
            for (int i = 0; i < M; i++)
            {
                scanf("%d%d", &U[i], &V[i]);
                AddEdge(U[i], V[i]);
            }
            Start = 1;
            End = N;
            Tarjan(1, -1);
            Slove();
            for (int i = 0; i < M; i++)
                if (Belong[U[i]] != Belong[V[i]])
                    SUM[Belong[U[i]]]++, SUM[Belong[V[i]]]++;
            int ANS = 0;
            for (int i = 1; i <= Block; i++) if (SUM[i] == 1) ANS++;
            if (ANS % 2 == 0) printf("%d
    ", ANS / 2);
            else printf("%d
    ", ANS / 2 + 1);
        }
        return 0;
    }
  • 相关阅读:
    浅析uitableview
    ios9和xcode7的适配问题
    uiviewContentMode的介绍 转载
    关于常见的加密算法浅析
    程序中发起电话呼叫
    单例实现方式以及类方法和实例方法
    windows下的git的安装教程
    上传github项目
    android 使用SurfaceView绘制一个简单动画控件
    android 自定义控件属性获取bitmap和drawable的绘制
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4767945.html
Copyright © 2020-2023  润新知