• HDU 6170 FFF at Valentine(强联通缩点+拓扑排序)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6165
    题意:给你一个无环,无重边的有向图,问你任意两点,是否存在路径使得其中一点能到达另一点
    解析:强联通后拓扑排序,因为对于每一层来说只能有一个入度为零的点,若存在两个,那么就会存在一对点不可达

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<bitset>
    #include<functional>
    
    using namespace std;
    
    #define LL long long
    const int INF = 0x3f3f3f3f;
    
    const int maxn = 1e5+100;
    vector<int>G[maxn];
    vector<int>rG[maxn];
    vector<int>vs;
    vector<int>g[maxn];
    queue<int> q;
    int vis[maxn],cmp[maxn];
    int in[maxn];
    void init(int n)
    {
        for(int i=0; i<=n; i++)
        {
            G[i].clear();
            rG[i].clear();
            g[i].clear();
        }
        while(!q.empty()) q.pop();
    }
    void addEdge(int u,int v)
    {
        G[u].push_back(v);
        rG[v].push_back(u);
    }
    void dfs(int u)
    {
        vis[u] = 1;
        for(int i=0; i<(int)G[u].size(); i++)
        {
            int v = G[u][i];
            if(!vis[v])
                dfs(v);
        }
        vs.push_back(u);
    }
    void rdfs(int u,int k)
    {
        vis[u] = 1;
        cmp[u] = k;
        for(int i=0; i<(int)rG[u].size(); i++)
        {
            int v = rG[u][i];
            if(!vis[v])
                rdfs(v,k);
        }
    }
    int scc(int n)
    {
        memset(vis,0,sizeof(vis));
        vs.clear();
        for(int i=1; i<=n; i++)
        {
            if(!vis[i])
                dfs(i);
        }
        memset(vis,0,sizeof(vis));
        int k = 0;
        for(int i=vs.size()-1; i>=0; i--)
        {
            if(!vis[vs[i]])
                rdfs(vs[i],k++);
        }
        memset(in,0,sizeof(in));
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)G[i].size(); j++)
            {
                int v = G[i][j];
                if(cmp[i]!=cmp[v])
                {
                    in[cmp[v]]++;
                    g[cmp[i]].push_back(cmp[v]);
                }
            }
        }
        return k;
    }
    int main(void)
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d %d",&n,&m);
            init(n);
            for(int i=0; i<m; i++)
            {
                int x,y;
                scanf("%d %d",&x,&y);
                addEdge(x,y);
            }
            int k=scc(n);
            int flag=0;
            for(int i=0; i<k; i++)
            {
                if(in[i]==0)
                {
                    q.push(i);
                    flag++;
                }
                if(flag==2)
                    break;
            }
            if(flag<2)
            {
                while(!q.empty())
                {
                    int now=q.front();
                    q.pop();
                    flag=0;
                    for(int i=0; i<(int)g[now].size(); i++)
                    {
                        int v=g[now][i];
                        in[v]--;
                        if(in[v]==0)
                        {
                            flag++;
                            q.push(v);
                        }
                        if(flag==2) break;
                    }
                    if(flag>=2) break;
                }
            }
            if(flag>=1)
                puts("Light my fire!");
            else
                puts("I love you my love and our love save us!");
        }
        return 0;
    }
  • 相关阅读:
    操作系统学习笔记:银行家算法的回顾和训练
    操作系统学习笔记:内存学习随笔
    操作系统笔记:内存的连续管理
    操作系统笔记:内存的离散管理
    操作系统:内存管理复习ing之页面置换算法
    马原学习日记1:实践
    bootstrap简单教程
    css-6(媒体识别)
    css-5(弹性盒子)
    css-3(旋转+过渡)
  • 原文地址:https://www.cnblogs.com/YingZhixin/p/7590126.html
Copyright © 2020-2023  润新知