zoukankan      html  css  js  c++  java
  • poj2762 Going from u to v or from v to u?

    poj 2762

    给定一个有向图,问任意两点能否满足u能到v,或者,v能到u。共有n个点,m条边,((0<n<1001, 0<m<6000))。

      这道题应该是判断弱连通图。首先肯定是缩点,然后出来一个dag。我按照课件里说的,首先想到判断出度和入度为零的点的个数是否大于1,但这个是错的,因为在一个橄榄状的图中,几个分叉的点不能到达彼此。所以只有橄榄状且没有分叉的图才是yes。也就等于从源点判断最长路为n的图,它才是yes。这样才A。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    inline int min(int x, int y){ return x<y?x:y; }
    inline int max(int x, int y){ return x<y?y:x; }
    
    const int maxn=1005, maxm=6005;
    class Graph{
    public:
        struct Edge{
            int to, next; Graph *belong;
            Edge& operator ++(){
                *this=belong->edge[next];
                return *this;
            }
            int operator *(){ return to; }
        };
        void reset(){
            cntedge=0;
            edge[0].to=-1;
            memset(fir, 0, sizeof(fir));
        }
        void addedge(int x, int y){
            Edge &e=edge[++cntedge];
            e.to=y, e.next=fir[x];
            e.belong=this, fir[x]=cntedge;
        }
        Edge getlink(int x){ return edge[fir[x]]; }
    private:
        Edge edge[maxm];
        int cntedge, fir[maxn];
    };
    Graph g, g_scc;
    int tt, n, m, time, dfn[maxn], low[maxn];
    int t, stack[maxn], instack[maxn];
    int cntscc, incnt, belong[maxn], in[maxn], dp[maxn];
    
    void tarjan(int now){
        //注意tarjan不用考虑父亲!
        int nowc;
        dfn[now]=low[now]=++time;
        stack[++t]=now; instack[now]=1;
        for (Graph::Edge e=g.getlink(now); ~*e; ++e){
            nowc=*e;
            if (instack[nowc])
                low[now]=min(low[now], dfn[nowc]);
            if (!dfn[nowc]){
                tarjan(nowc);
                low[now]=min(low[now], low[nowc]);
            }
        }
        if (dfn[now]==low[now]){
            ++cntscc;
            //这里只能用dowhiles
            do{
                belong[stack[t]]=cntscc;
                instack[stack[t]]=0;
                --t;
            }while (dfn[stack[t+1]]!=low[stack[t+1]]);
        }
    }
    
    int dfs(int now){
        int nc, re=0;
        for (Graph::Edge e=g_scc.getlink(now); ~*e; ++e){
            nc=*e;
            if (!dp[nc]) re=max(dfs(nc), re);
            else re=max(dp[nc], re);
        }
        dp[now]=re+1;
        return re+1;
    }
    
    void init(){
        g.reset(); g_scc.reset();
        time=0; cntscc=0; incnt=0;
        memset(dp, 0, sizeof(dp));
        memset(in, 0, sizeof(in));
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
    }
    
    //考虑中途分叉的情况!所以只能跑dag最长路!
    int main(){
        scanf("%d", &tt);
        int x, y, nc, start;
        while (tt--){
            init();
            scanf("%d%d", &n, &m);
            for (int i=0; i<m; ++i){
                scanf("%d%d", &x, &y);
                g.addedge(x, y);
            }
            for (int i=1; i<=n; ++i)
                if (!dfn[i]) tarjan(i);
            for (int i=1; i<=n; ++i)
                for (Graph::Edge e=g.getlink(i); ~*e; ++e){
                    nc=*e;
                    if (belong[i]!=belong[nc]){
                        g_scc.addedge(belong[i], belong[nc]);
                        ++in[belong[nc]];
                    }
                }
            for (int i=1; i<=cntscc; ++i)
                if (!in[i]) start=i;
            if (dfs(start)==cntscc) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    python读取配置文件 ConfigParser
    python中引号中有双引号
    L​i​n​u​x​下​的​D​a​e​m​o​n​简​介(转)
    华为离职副总裁徐家骏:年薪千万的工作感悟(转)
    《码农周刊》干货精选--Python篇(转)
    三个在线django速成教程(转)
    互联网架构学习相关资料(转)
    人人网张铁安:Feed系统架构分析(转)
    用 mongodb 储存多态消息/提醒类数据(转)
    关于如何构建一个微博型广播 二(转)
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7613698.html
Copyright © 2011-2022 走看看