zoukankan      html  css  js  c++  java
  • HDU

    CRB and Roads

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 495    Accepted Submission(s): 225

    Problem Description
    There are N cities in Codeland.
    The President of Codeland has a plan to construct one-way roads between them.
    His plan is to construct M roads.
    But CRB recognized that in this plan there are many redundant roads.
    So he decided to report better plan without any redundant roads to President.
    Help him!
    The road (uv) is redundant if and only if there exists a route from u to v without using it.
     
    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
    The first line contains two integers N and M denoting the number of cities and the number of roads in the President’s plan.
    Then M lines follow, each containing two integers u and v representing a one-way road from u to v.
    1 ≤ T ≤ 20
    1 ≤ N ≤ 2 * 104
    1 ≤ M ≤ 105
    1 ≤ uv ≤ N
    The given graph is acyclic, and there are neither multiple edges nor self loops.

     
    Output
    For each test case, output total number of redundant roads.
     
    Sample Input
    1 5 7 1 2 1 3 1 4 1 5 2 4 2 5 3 4
     
    Sample Output
    2

     题目链接 

    题意 

    给一个简单无环有向图,求出冗余边的个数。冗余边即若删去u->v,仍能从u走到v,这样的边就是一条冗余边。

    分析 

    对于每个点,记录一下有哪些点可以到达这个点,由于是简单无环图,可以用拓扑排序搞定,拓扑排序的过程中记录下当前点的所有前驱点。然后,根据前驱点的拓扑序号,从大到小遍历维护更新这个可达矩阵,在更新之前先检查其前驱在这条边之前是否已可达当前点,是的话就说明是冗余边。

    还有一个问题,用简单的二维数组当作矩阵来记录会超时的,所以我们使用bitset来记录可达状态,bitset[i][j]表示可从j点到达i点,这样更新时只用or一下,优化了时间。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include <queue>
    #include <vector>
    #include<bitset>
    using namespace std;
    typedef long long LL;
    
    const int mod = 772002+233;
    typedef pair<int,int> pii;
    #define X first
    #define Y second
    #define pb push_back
    //#define mp make_pair
    #define ms(a,b) memset(a,b,sizeof(a))
    const int maxn = 2e4 + 10;
    vector<vector<int> > G,mp;
    int in[maxn];
    int rec[maxn];
    int top;
    int n, m;
    void topo() {
        top = 0;
        for (int i = 1;i <= n;++i)
            if (in[i] == 0)
                rec[top++] = i;
        for (int i = 0;i < top;++i) {
            int u = rec[i];
            int Size = G[u].size();
            for (int j = 0;j < Size;++j) {
                int v = G[u][j];
                mp[v].push_back(u); //v的前驱结点u
                if (--in[v] == 0) rec[top++] = v;
            }
        }
    }
    bitset<maxn> bit[maxn];
    
    int main(){
    //     freopen("in.txt","r",stdin);
        // freopen("out.txt","w",stdout);
    
        int kase;
        cin >> kase;
        while(kase--) {
            cin >> n >> m;
            G.clear();G.resize(n + 2);
            mp.clear();mp.resize(n + 2);
            int u, v;
            memset(in, 0, sizeof(in));
            for (int i = 1;i <= m;++i) {
                scanf("%d%d", &u, &v);
                G[u].push_back(v);
                in[v]++;
            }
            topo();
            // for (int i = 0;i < top;++i)
            //     cout << rec[i] << ' ';
            // cout << endl;
            for (int i = 0;i <= n;++i) {
                bit[i].reset();
                bit[i].set(i);
            }
            int ans = 0;
            for (int i = 0;i < top;++i) {
                int u = rec[i];
    //            cout<<u<<endl;
                int Size = mp[u].size();
                for (int j =Size-1;j >=0;--j) {
                    int v = mp[u][j]; //v->u
    //                printf("%d->%d
    ",v,u);
                    if (bit[u][v]) ans++; //冗余
                    bit[u] |= bit[v];//能到达v的也能到达u
                }
    
            }
            cout << ans << endl;
        }
        return 0;
    }
  • 相关阅读:
    常见运算符_python
    hibernate中的二级缓存
    事务的隔离级别
    java hibernate 一对多和多对多映射关系总结
    hibernate中集合映射总结
    java中静态代码块之我的理解
    select下拉表达设置选中,获取选中项,change
    jquery checkbox设置选中,全选,反选,取值
    javaWeb建立一个简单三层项目具体步骤
    java 异步实现省市联动
  • 原文地址:https://www.cnblogs.com/fht-litost/p/8552900.html
Copyright © 2011-2022 走看看