zoukankan      html  css  js  c++  java
  • HDU 2767-Proving Equivalences(强联通+缩点)

    题目地址:HDU 2767
    题意:给一张有向图。求最少加几条边使这个图强连通。
    思路:先求这张图的强连通分量。假设为1。则输出0(证明该图不须要加边已经是强连通的了)。否则缩点。

    遍历原图的全部边。假设2个点在不同的强连通分量里面,建边,构成一张新图。统计新图中点的入度和出度,取入度等于0和出度等于0的最大值(由于求强连通缩点后。整张图就变成了一个无回路的有向图。要使之强连通。仅仅须要将入度=0和出度=0的点加边就可以,要保证加边后没有入度和出度为0的点,所以取两者最大值)
    PS:补充一下缩点的含义:我们求强连通分量时,给每一个顶点做一个标记,标记该顶点属于哪个强联通分量,然后属于同一个强连通分量的点就能够看作同一个点了。

    这就是所谓的“缩点”

    *#include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <set>
    #include <queue>
    #include <stack>
    #include <map>
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const double pi= acos(-1.0);
    const double esp=1e-6;
    const int maxn=21010;
    int head[maxn],dfn[maxn],low[maxn],belong[maxn],stak[maxn],instack[maxn];
    int in[maxn],out[maxn];
    int incnt,outcnt;
    int cnt,index,top,ans;
    struct node {
        int u, v, next;
    } edge[maxn*3];
    void add(int u, int v) {
        edge[cnt].v=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void Init() {
        memset(head,-1,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(instack,0,sizeof(instack));
        cnt=index=top=ans=0;
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        incnt=outcnt=0;
    }
    void tarjan(int u) {
        dfn[u]=low[u]=++index;
        stak[++top]=u;
        instack[u]=1;
        for(int i=head[u]; i!=-1; i=edge[i].next) {
            int v=edge[i].v;
            if(!dfn[v]) {
                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]) {
            ans++;
            while(1) {
                int v=stak[top--];
                instack[v]=0;
                belong[v]=ans;
                if(u==v) break;
            }
        }
    }
    int main() {
        int T, n, m,i, j;
        int u,v;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&m);
            Init();
            while(m--) {
                scanf("%d%d",&u,&v);
                add(u,v);
            }
            for(i=1; i<=n; i++) {
                if(!dfn[i])
                    tarjan(i);
            }
            if(ans==1) {
                printf("0
    ");
                continue ;
            }
            for(i=1; i<=n; i++) {
                for(j=head[i]; j!=-1; j=edge[j].next) {
                    int v=edge[j].v;
                    if(belong[v]!=belong[i]) {
                        in[belong[v]]++;
                        out[belong[i]]++;
                    }
                }
            }
            for(i=1; i<=ans; i++) {
                if(!in[i])
                    incnt++;
                if(!out[i])
                    outcnt++;
            }
            printf("%d
    ",max(incnt,outcnt));
        }
        return 0;
    }*
    
  • 相关阅读:
    HTML Rendering Error
    PyCharm将选中的内容加上引号
    Scrapy中的Request和日志分析
    PyCharm关闭按两次Shift进入搜索框的功能
    博客园更换模板的链接
    Scrapy的Spider类和CrawlSpider类
    Scrapy安装和简单使用
    计算π的近似值
    Python用pip安装第三方库时换源下载
    网页解析 -- bs4 和 xpath 的简单使用
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8490633.html
Copyright © 2011-2022 走看看