zoukankan      html  css  js  c++  java
  • Network POJ

    就是求出原先图中的桥的数量,在每一次询问时加入一条新边,求加入当前边后图中剩余的桥的数量

    求出原先图中的桥的数量,然后减去新加入边的两端点之间的桥的数量,就是剩余桥的数量。。

    用并查集把属于同一集合的放到一起(即两个点之间没有桥的)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #define mem(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 400100, INF = 0x7fffffff;
    int pre[maxn], f[maxn], pa[maxn];
    int dfs_clock;
    int n, m, ret;
    vector<int> G[maxn];
    int find(int x)
    {
        return f[x]==x?x:(f[x]=find(f[x]));
    }
    
    int Union(int u, int v)
    {
        int r = find(u);
        int l = find(v);
        if(r == l) return 0;
        f[r] = l;
        return 1;
    }
    
    
    int dfs(int u, int fa)
    {
        pa[u] = fa;
        int lowu = pre[u] = ++dfs_clock;
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(!pre[v])
            {
         //       pa[v] = u;
                int lowv = dfs(v, u);
                lowu = min(lowu, lowv);
                if(lowv > pre[u])
                    ret++;
                else
                    Union(u, v);   //如果u和v之间没桥,那么u和v就同属于一个集合
            }
            else if(pre[v] < pre[u] && v != fa)
                lowu = min(lowu, pre[v]);
        }
    
        return lowu;
    }
    
    int lca(int u, int v)
    {
        int r = find(u);
        int l = find(v);
        if(r == l)
            return ret;
        if(pre[u] > pre[v])
            swap(u, v);
        while(pre[u] < pre[v])
        {
            if(Union(pa[v], v))
                ret--;
            v = pa[v];
        }
        while(u != v)     //v经过上一个while后要么是u 要么是u和v的最近公共祖先
        {
            if(Union(u, pa[u]))
                ret--;
            u = pa[u];
        }
        return ret;
    }
    
    void init()
    {
        mem(pre, 0);
        mem(pa, 0);
        for(int i=0; i<=n; i++) f[i] = i;
        dfs_clock = 0;
        ret = 0;
    }
    
    int main()
    {
        int kase = 0;
        while(cin>> n >> m && n+m)
        {
            init();
            for(int i=0; i<m; i++)
            {
                int u, v;
                cin>> u >> v;
                G[u].push_back(v);
                G[v].push_back(u);
            }
            dfs(1, -1);
            int Q;
            cin>> Q;
            printf("Case %d:
    ",++kase);
            for(int i=0; i<Q; i++)
            {
                int u, v;
                cin>> u >> v;
                cout<< lca(u, v) <<endl;
            }
    
        }
    
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    Data Structure(2)
    CoreAnimation —— CALayer
    [置顶] android AIDL 进程间通信
    UVA 10057 A mid-summer night's dream. 仲夏夜之梦 求中位数
    基于mini2440的IIC读写(裸机)
    外媒关注:中国法庭用新浪微薄直播薄熙来审判
    [置顶] 吃论扯谈---吃货和Office 365订阅的关系
    小智慧42
    机器学习如何选择模型 & 机器学习与数据挖掘区别 & 深度学习科普
    【Todo】【转载】Spark学习 & 机器学习(实战部分)-监督学习、分类与回归
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9302594.html
Copyright © 2011-2022 走看看