zoukankan      html  css  js  c++  java
  • 求最小点基 poj 1236

    题意:

    在一个信息网络当中,为了能够告知学校最新信息,现在告诉你各个学校之间的联系关系,问你最少能够通知多少个学校就能完成对所有的学校通知完毕,因为具有内在联系的学校会相互通知,若我们现在想要通知其中一个学校就能通过它们内部传递然后就能使所有学校都知道,那么此时我们使某些学校存在一个联系就可以了,问这样的联系我们最少需要创建多少。

    解题思路:只要算出强连通的个数,并且知道哪些强连通没有入度,计数,然后第二个答案只要计数所有强连通入度为0,出度为0的个数,然后取两者最大值,这就是要添加的最少边数。。

    View Code
     1   #include<iostream>
     2   #include<stdio.h>
     3   #define min(a,b) a<b?a:b
     4   #define max(a,b) a>b?a:b
     5   #define S 110
     6   using namespace std;
     7   int n;
     8   int map[S][S],stack[S],dfn[S],low[S],top,Time,exist[S],weight[S],Count,ind[S],outd[S];
     9   void tarjan(int u)
    10   {
    11        dfn[u]=low[u]=++Time;
    12        stack[top++]=u;
    13        exist[u]=1;
    14        for(int to=1;to<=n;to++)
    15        {
    16             if(!dfn[to]&&map[u][to]==1)
    17             {
    18                 tarjan(to);
    19                 low[u]=min(low[u],low[to]);    
    20             }
    21             else
    22             {
    23                 if(map[u][to]==1&&exist[to]==1)
    24                 low[u]=min(low[u],dfn[to]);
    25             }
    26        } 
    27        if(low[u]==dfn[u])
    28        {
    29               Count++;
    30               int v;
    31               do
    32               {
    33                    v=stack[top-1];
    34                    exist[v]=0;
    35                    weight[v]=Count;
    36                    top--;
    37               }while(u!=v);
    38        }
    39   }
    40   int main()
    41   {
    42      int end;
    43      while(scanf("%d",&n)!=EOF)
    44      {
    45         for(int i=1;i<=n;i++)
    46         {
    47             for(int j=1;j<=n;j++)
    48             {
    49              if(i==j)map[i][j]=1;
    50              else
    51              map[i][j]=-1;
    52             }
    53             ind[i]=outd[i]=exist[i]=dfn[i]=low[i]=0;
    54         }
    55         for(int i=1;i<=n;i++)
    56         {
    57             scanf("%d",&end);
    58             while(end)
    59             {
    60                    map[i][end]=1;
    61                    scanf("%d",&end);
    62             }
    63         }
    64         Count=Time=top=0;
    65         for(int i=1;i<=n;i++)
    66         {
    67            if(!dfn[i])
    68               tarjan(i);
    69         }
    70         for(int i=1;i<=n;i++)
    71         {
    72            for(int j=1;j<=n;j++)
    73            {
    74                if(map[i][j]==1&&weight[i]!=weight[j])
    75                {
    76                      ind[weight[j]]++;
    77                      outd[weight[i]]++;                           
    78                }        
    79            }        
    80         }
    81         int max1=0,max2=0;
    82         for(int i=1;i<=Count;i++)
    83         {
    84             if(ind[i]==0)max1++;
    85             if(outd[i]==0)max2++;
    86         }
    87         max2=max(max1,max2);
    88         printf("%d\n",max1);
    89         if(Count==1)printf("0\n");
    90         else
    91         printf("%d\n",max2); 
    92      } 
    93      return 0;    
    94   }
  • 相关阅读:
    2.6
    20、算法的复杂度
    SVN的部署及分支等方法
    19、数据库设计的三大范式
    2.ViewBag、ViewData、TempData之间的区别
    1、MVC和EF中的 Model First 和 Code First
    19、lambda表达式树
    12、c#中事务及回滚
    11、Linq的使用
    18、(番外)匿名方法+lambda表达式
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2667112.html
Copyright © 2011-2022 走看看