zoukankan      html  css  js  c++  java
  • poj1236学校网络——连通块

    题目:http://poj.org/problem?id=1236

    通过传输文件的特点可以看出要先求强联通分量,缩点;

    问题1:即缩点后入度为0的点,从它们开始传文件可以传给所有学校;

    问题2:对于所有入度为0、出度为0的点,对应连一条边;多余的随便再连一下就可以,所以答案是max(入度为0点数,出度为0点数);

    需要特判一下没有入度为0的点,也就是整个图是一个强联通分量时,输出1和0。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const MAXN=105;
    int n,head[MAXN],ct,dfn[MAXN],low[MAXN],rd[MAXN],cd[MAXN],ans,sta[MAXN],tim,top;
    int cr,col[MAXN],r0,c0;
    bool vis[MAXN];
    struct N{
        int hd,to,next;
        N(int h=0,int t=0,int n=0):hd(h),to(t),next(n) {}
    }edge[MAXN*MAXN];
    void tarjan(int x)
    {
    //    cout<<x<<endl;
        tim++;
        dfn[x]=tim;low[x]=tim;
        vis[x]=1;sta[++top]=x;
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(!dfn[u])
            {
                tarjan(u);
                low[x]=min(low[x],low[u]);
            }
            else if(vis[u])
                low[x]=min(low[x],dfn[u]);
        }
        if(dfn[x]==low[x])
        {
            cr++;
            while(sta[top]!=x)
            {
                int t=sta[top];
                vis[t]=0;col[t]=cr;
                top--;
            }
            vis[x]=0;col[x]=cr;top--;
        }
    }
    int main()
    {
        scanf("%d",&n);
        int x;
        for(int i=1;i<=n;i++)
            while(1)
            {
                scanf("%d",&x);
                if(!x)break;
                edge[++ct]=N(i,x,head[i]);head[i]=ct;
            }
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i);
        for(int i=1;i<=ct;i++)
        {
            int u=edge[i].hd;
            int v=edge[i].to;
            if(col[u]!=col[v])
            {
                rd[col[v]]++;cd[col[u]]++;
            }
        }
        for(int i=1;i<=cr;i++)
        {
            if(!rd[i])r0++;
            if(!cd[i])c0++;
        }
        if(cr==1)printf("1
    0");
        else printf("%d
    %d",r0,max(r0,c0));
        return 0;
    }
  • 相关阅读:
    F#学习开篇(一)
    F#学习(二)
    认识“闭包”
    Silverlight显示控件换行的几种方式
    关于P问题、NP问题、NPC问题
    LINQ&EF任我行(二)LinQ to Object
    WPF中资源的引用方法
    Linq to EF 与Linq to Object 使用心得
    C#中如何用拼音模糊匹配汉字的首字母
    WPF获取应用程序路径方法,获取程序运行路径方法
  • 原文地址:https://www.cnblogs.com/Zinn/p/8868519.html
Copyright © 2011-2022 走看看