zoukankan      html  css  js  c++  java
  • hdu6165 缩点,dfs

    hdu6165    FFF at Valentine

    题意:给出一个有向图,问任意两个点 a、b,是否可以从a到b,或者从b到a。

    tags:主要是题意有点绕。。 只要 tarjan 缩点成 DAG图,再 dfs 判断一下在 DAG 图中是否有一条路径包含了所有点。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 6005;
    
    int n, m;
    struct Edge{ int from, to, next; } e[N*2];
    int Stack[N<<2], dfn[N], low[N], Belong[N], sz[N], head[N];
    bool instack[N];
    int top, tot, sum, tot1;
    void Addedge(int u,int v) { e[tot]={u, v, head[u]}; head[u]=tot++; }
    void Tarjan(int u)
    {
        dfn[u]=low[u]=++tot1;
        Stack[top++]=u, instack[u]=1;
        for(int i=head[u]; i!=-1; i=e[i].next) {
            int v=e[i].to;
            if(dfn[v]==0) {
                Tarjan(v);
                low[u]=min(low[u], low[v]);
            }
            else if(instack[v]) low[u]=min(low[u], dfn[v]);
        }
        if(dfn[u]==low[u]) {
            sum++;
            while(top!=0) {
                int en=Stack[--top];
                instack[en]=0;
                Belong[en]=sum;
                sz[sum]++;
                if(en==u) break;
            }
        }
    }
    vector<int > G[N<<1];
    int in[N], s1;
    void Init()
    {
        mes(head, -1);  mes(Stack, 0);  mes(dfn, 0);
        mes(Belong, 0);  mes(sz, 0);  mes(instack, false);
        mes(low, 0);
        mes(in, 0);
        rep(i,0,(N<<1)-1) G[i].clear();
        sum = tot = tot1 = top = s1 = 0;
    }
    bool dfs(int u)
    {
        ++s1;
        if(s1==sum) return true;
        for(int i=0; i<G[u].size(); ++i)
        {
            if(dfs(G[u][i])) return true;
        }
        --s1;
        return false;
    }
    int main()
    {
        int T;  scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d", &n, &m);
            Init();
            int u, v;
            rep(i,1,m)
            {
                scanf("%d%d", &u, &v);
                Addedge(u, v);
            }
            rep(i,1,n) if(dfn[i]==0) Tarjan(i);
            bool flag=0;
            rep(i,0,tot-1)
            {
                u=Belong[e[i].from], v=Belong[e[i].to];
                if(u!=v)  G[u].PB(v), ++in[v];
            }
            int ro, num=0;
            rep(i,1,sum) if(in[i]==0) ro=i, ++num;
            if(num>1) flag=1;
            else if(!dfs(ro)) flag=1;
            if(flag==0) puts("I love you my love and our love save us!");
            else puts("Light my fire!");
        }
    
        return 0;
    }
  • 相关阅读:
    dtoi2680「SDOI2016」生成魔咒
    dtoi2679「SDOI2016」游戏
    dtoi2678「SDOI2016」数字配对
    dtoi2677「SDOI2016」储能表
    dtoi4545「HNOI2016」树
    dtoi4543「HNOI2016」最小公倍数
    dtoi4544「HNOI2016」网络
    dtoi4548「HNOI2016」大数
    ts定义数组对象
    RN项目ios本地模拟机无法加载本地图片的解决方案
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7413193.html
Copyright © 2011-2022 走看看