zoukankan      html  css  js  c++  java
  • poj 1236 强联通分量

    大致题意给你有一个点数为n<=100的有向图。

    求解两个子任务:

    1:最少给多少个点信息,这些点的信息可以顺着有向边传遍全图。

    2:最少要加多少条边,使得整个图强联通。

    求强联通分量再缩点后得到一个有向无环图。

    设其入度为0的点数为t1,出度为0的点数为t2

    1的答案即为强联通缩点之后入度为0的点的数量t1。

    2的答案即为max(t1,t2).

    注意一个特殊情况:若缩点后只有一个点了(即原图便是强联通的)此时t1=1,t2=1但是第二个任务的答案应当是0。

    AC代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int MAXN=110;
    int n,cnt;
    int graph[MAXN][MAXN];
    int DFN[MAXN],low[MAXN],Stap[MAXN],label[MAXN];
    bool instake[MAXN];
    int Stop,Bcnt;
    int adjm[MAXN][MAXN];
    int in[MAXN],out[MAXN];
    void init()
    {
        memset(graph,0,sizeof(graph));
        memset(DFN,0,sizeof(DFN));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(adjm,0,sizeof(adjm));
        memset(instake,0,sizeof(instake));
        int t;
        cnt=0;Stop=0;Bcnt=0;
        rep(i,1,n)
        {
            while(scanf("%d",&t)==1&&t)
            {
                graph[i][++graph[i][0]]=t;
            }
        }
    }
    void tarjan(int u)
    {
        DFN[u]=low[u]=++cnt;
        instake[u]=1;
        Stap[++Stop]=u;
        rep(i,1,graph[u][0])
        {
            int v=graph[u][i];
            if(!DFN[v])
            {
                tarjan(v);
                if(low[v]<low[u]) low[u]=low[v];
            }
            else if(instake[v]&&DFN[v]<low[u]) low[u]=DFN[v];
        }
        int j;
        if(DFN[u]==low[u])
        {
            ++Bcnt;
            do
            {
                j=Stap[Stop--];
                instake[j]=0;
                label[j]=Bcnt;
            }while(j!=u);
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&n)==1)
        {
            init();
            rep(i,1,n)
            {
                if(!DFN[i]) tarjan(i);
            }
            if(Bcnt==1)
            {
                    printf("1
    0
    ");continue;
            }
            rep(i,1,n)
            {
                rep(j,1,graph[i][0])
                {
                    int v=graph[i][j];
                    if(label[i]!=label[v])
                    {
                        out[label[i]]++;
                        in[label[v]]++;
                    }
                }
            }
            int t1=0,t2=0;
            rep(i,1,Bcnt)
            {
                if(in[i]==0) t1++;
                if(out[i]==0) t2++;
            }
            printf("%d
    %d
    ",t1,max(t1,t2));
        }
        return 0;
    }
  • 相关阅读:
    pycharm快捷键
    Java线程的生命周期
    Java中的管程
    Java并发编程之入门
    Linux系统监控命令
    RT-Thread 搜集一些其他博主的博客以备学习
    late_initcall 替换 module_init
    去掉行尾的^M
    ST3 C程序自动补全
    MinGW-W64 编译 LLVM 与 Clang
  • 原文地址:https://www.cnblogs.com/zhixingr/p/7822422.html
Copyright © 2011-2022 走看看