zoukankan      html  css  js  c++  java
  • HDU 6165-强连通分量+拓扑

    题意

    给出一幅有向图,判定是否存在一对顶点互相不可达。

    分析

    在一个强连通分量里的点对是互相可达的,我们先求出强连通分量再缩点构建新图

    然后我们对新图进行拓扑排序,当开始时或者删完一个点及它的关联边时,若入度为0的点多于1个,则这些点互相不可达

    代码

    #include <map>
    #include <set>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define MAX     10007
    #define MAXN      10007
    #define MAXM      20007
    #define INF  0x3f3f3f3f
    #define NINF 0xc0c0c0c0
    #define MOD  1000000007
    using namespace std;
    typedef long long LL;
    struct Edge{int to,next;}edge[MAXM];
    int head[MAXN],tot;
    int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
    int Index,top;
    int scc;//强连通分量的个数
    bool Instack[MAXN];
    int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
    //num数组不一定需要,结合实际情况
    void addEdge(int u,int v) {
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void Tarjan(int u) {
        int v;
        Low[u]=DFN[u]=++Index;
        Stack[top++]=u;
        Instack[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].to;
            if(!DFN[v]){
                Tarjan(v);
                if(Low[u]>Low[v])Low[u]=Low[v];
            }
            else if(Instack[v]&&Low[u]>DFN[v])
                Low[u]=DFN[v];
        }
        if(Low[u]==DFN[u]){
            scc++;
            do{
                v=Stack[--top];
                Instack[v]=false;
                Belong[v]=scc;
                num[scc]++;
            }while(v!=u);
        }//printf("scc=%d
    ",scc);
    }
    void solve(int N) {
        memset(DFN,0,sizeof DFN);
        memset(Instack,false,sizeof Instack);
        memset(num,0,sizeof num);
        Index=scc=top=0;
        for(int i=1;i<=N;i++)
            if(!DFN[i])Tarjan(i);
    }
    Edge edge1[MAXM];
    int tot1,head1[MAXN],odeg1[MAXN],indegree[MAXN];
    void addEdge1(int u,int v) {
        odeg1[u]++;
        indegree[v]++;
        edge1[tot1].to=v;
        edge1[tot1].next=head1[u];
        head1[u]=tot1++;
    }
    void reduce(int N){
        tot1=0;
        memset(head1,-1,sizeof head1);
        memset(odeg1,0,sizeof odeg1);
        memset(indegree,0,sizeof indegree);
        for(int u=1;u<=N;u++){
            for(int k=head[u];k!=-1;k=edge[k].next){
                int v=edge[k].to;
                if(Belong[u]!=Belong[v]){
                    addEdge1(Belong[u],Belong[v]);
                }
            }
        }
    }
    bool topo(int n){
        priority_queue<int, vector<int>,greater<int> > Q;
        int ans[MAXN],iq=0;
        for(int i=1;i<=n;i++){
            //printf("%d
    ",indegree[i]);
            if(indegree[i]==0) Q.push(i);
        }
        //
        if(Q.size()!=1)return false;//printf("flag1
    ");
        while(!Q.empty()){//printf("sizeof q is %d
    ",Q.size());
            if(Q.size()!=1)return false;
            int qt=Q.top();
            ans[iq++]=qt;
            Q.pop();
            for(int k=head1[qt];k!=-1;k=edge1[k].next){
                int t=edge1[k].to;
                indegree[t]--;
                if(indegree[t]==0) Q.push(t);
            }
        }
        return true;
    }
    void init() {
        tot=0;
        memset(head,-1,sizeof head);
    }
    
    int main(){
        int cas,n,m,u,v;
        scanf("%d",&cas);
        while(cas--){
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                scanf("%d%d",&u,&v);
                addEdge(u,v);
            }
            solve(n);
            reduce(n);
            printf(topo(scc)?"I love you my love and our love save us!
    "
            :"Light my fire!
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    合并指定表格指定列的相同文本的相邻单元格
    [转载]>/dev/null 2>&1 含义
    有关cron
    jQuery版本对checkbox影响
    c# 如何获取项目的根目录
    Javascript 字符串组装用函数 format
    sql server 删除数据库
    说说接口封装
    有开放的接口!!!!
    支付宝支付功能的集成
  • 原文地址:https://www.cnblogs.com/shuiming/p/7413773.html
Copyright © 2011-2022 走看看