zoukankan      html  css  js  c++  java
  • HDU 3749 Financial Crisis

    Financial Crisis

    题意:给一个图,包含N ( 3 <= N <= 5000 )个点, M ( 0 <= M <= 10000 )条边 and Q ( 1 <= Q <= 1000 )次查询.查询:两个点是否是点-双连通;

    点-双连通:两点至少存在两条"点不重复"的路径;简称双连通(biconnected);

    思路:直接调用dfs求割点的算法,其实也是Tarjan发明的,就是在判断出一个割点之后,就把栈S中该双连通分量的所有点(就在栈顶)insert到同一个集合中;

    注意:一个点可以属于多个双连通分类,所以bccno数组其实只是一个防止重复insert同一个点,在set中可以除去。并且注意初始化各种数组即序号(这样都TLE几次)

    PS:原本使用链式向前星来存储边,可是发现在hd里竟然比直接vector建图还慢。。(一脸茫然);并且开始使用stack<PII> 直接MLE了,可是看别人直接使用库栈。。

    #include<iostream>
    #include<sstream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    #include<set>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    
    const int MAXN = 10010;
    int low[MAXN],pre[MAXN],dfs_clock,bcc_cnt;
    int bccno[MAXN];//看点属于哪个双连通分量;
    set<int> bcc[MAXN];//存储每一个双连通分量的点的标号;
    typedef pair<int,int> PII;
    #define A first
    #define B second
    #define pb push_back
    PII S[MAXN<<1];//存储边,从中取点
    vector<int> e[MAXN];
    int top;
    int dfs(int u,int fa)
    {
        int lowu = pre[u] = ++dfs_clock;
        int child = 0;
        rep0(i,0,e[u].size()){
            int v = e[u][i];
            PII e = PII{u,v};
            if(!pre[v]){
                S[++top] = e;
                child++;
                int lowv = dfs(v,u);
                lowu = min(lowu,lowv);//以子节点的low来更新u的low函数;
                if(lowv >= pre[u]){ //表示u-v为桥
                    bcc[++bcc_cnt].clear();
                    for(;;){
                        PII x = S[top--];
                        if(bccno[x.A] != bcc_cnt){bcc[bcc_cnt].insert(x.A);bccno[x.A] = bcc_cnt;}//就是为了不重复加点
                        if(bccno[x.B] != bcc_cnt){bcc[bcc_cnt].insert(x.B);bccno[x.B] = bcc_cnt;}
                        if(x.A == u && x.B == v) break;//根据加入的顺序知,正好对应;
                    }
                }
            }
            else if(v != fa && pre[v] < pre[u]){
                S[++top] = e;
                lowu = min(lowu,pre[v]);
            }
        }
        return low[u] = lowu;
    }
    int f[MAXN];
    int Find(int a)
    {
        return a==f[a]?f[a]:f[a]=Find(f[a]);
    }
    char ans[][15] = {"zero","one","two or more"};
    int main()
    {
        int N,M,Q,kase = 1;
        while(scanf("%d%d%d",&N,&M,&Q) == 3 && N+M+Q){
            rep0(i,0,N){
                f[i] = i;
                e[i].clear();//直接vector建图
            }
            int u,v;
            rep0(i,0,M){
                scanf("%d%d",&u,&v);
                e[u].pb(v);e[v].pb(u);
                u = Find(u),v = Find(v);
                if(u != v) f[v] = u;
            }
            bcc_cnt = dfs_clock = top = 0;
            MS0(pre);MS0(bccno);
            rep0(i,0,N)if(pre[i] == 0)
                dfs(i,-1);
            printf("Case %d:
    ",kase++);
            rep0(i,0,Q){
                int ret;
                scanf("%d%d",&u,&v);
                if(Find(u) != Find(v)) ret = 0;
                else{
                    ret = 1;
                    rep1(j,1,bcc_cnt){
                        if(bcc[j].find(u) != bcc[j].end() && bcc[j].find(v) != bcc[j].end()&&bcc[j].size() > 2)
                            ret = 2;
                    }
                }
                printf("%s
    ",ans[ret]);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ADODB.Recordset错误800a0cb3"的解决方
    C++ primer第一章 C++概述 纪要
    [收藏]一些电平转换方法
    “当传递具有已修改行的 DataRow 集合时,更新要求有效的 UpdateCommand”错误解决
    关于句柄的一些知识 Handle (computing) Wiki
    “/”应用程序中的服务器错误。当前标识(NT AUTHORITY/NETWORK SERVICE)没有对“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files”的写访问权
    C++中 __stdcall,__cdecl, __fastcal区别简介
    [How To]使用Wildfish进行开发新Solution配置篇
    关于ISeries的代码生成器
    [How To]如何使用Wildfish进行ISeries项目开发数据库建立部分
  • 原文地址:https://www.cnblogs.com/hxer/p/5184605.html
Copyright © 2011-2022 走看看