zoukankan      html  css  js  c++  java
  • 【CCF】高速公路 tarjan强连通缩点

    【题意】

    给定一个有向图,问图中互相可达(强连通)的点有多少对

    【AC】

    强连通缩点,缩点后是一个DAG,所以互相可达的点只在强连通块里。

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    int n,m;
    const int maxn=1e4+2;
    const int maxm=1e5+2;
    struct edge{
        int to;
        int nxt;
    }e[maxm];
    int head[maxn];
    int tot;
    int S[maxn],top;
    int dfn[maxn],low[maxn],id;
    int belong[maxn],num;
    bool vis[maxn];
    int circle[maxn];
    void init(){
        memset(head,-1,sizeof(head));
        tot=0;
        id=top=num=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(vis,false,sizeof(vis));
        memset(circle,0,sizeof(circle));
    }
    void add(int u,int v){
        e[tot].to=v;
        e[tot].nxt=head[u];
        head[u]=tot++;
    }
    void tarjan(int u)
    {
        dfn[u]=low[u]=++id;
        S[++top]=u;
        vis[u]=true;
        for(int i=head[u];i!=-1;i=e[i].nxt)
        {
            int v=e[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v]) low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            num++;
            while(1)
            {
                belong[S[top]]=num;
                vis[S[top]]=false;
                if(S[top--]==u) break;
            }
        }
    }
    
    int main(){
        while(~scanf("%d%d",&n,&m)){
            init();
            int u,v;
            for(int i=1;i<=m;i++){
                scanf("%d%d",&u,&v);
                add(u,v);    
            }
            for(int i=1;i<=n;i++){
                if(!dfn[i]) tarjan(i);
            }
            for(int i=1;i<=n;i++){
                circle[belong[i]]++; 
            }
            int ans=0;
            for(int i=1;i<=num;i++){
                ans+=circle[i]*(circle[i]-1)/2;
            }
            printf("%d
    ",ans);
        }
        return 0;
    } 
  • 相关阅读:
    cmd中编译java
    java出错
    去掉开始菜单中新装程序的红色标记【Windows】
    Windows安装java
    看视频缓冲好还一卡一卡【解决】
    python图像卷积
    电脑硬盘、内存
    python 查询Neo4j多节点的多层关系
    python 快速排序实现
    python 二分法实现
  • 原文地址:https://www.cnblogs.com/itcsl/p/9192589.html
Copyright © 2011-2022 走看看