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;
    }
  • 相关阅读:
    学期总结
    C语言I博客作业09
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言II—作业04
    C语言II—作业03
    C语言II—作业02
    C语言II博客作业01
  • 原文地址:https://www.cnblogs.com/zhixingr/p/7822422.html
Copyright © 2011-2022 走看看