zoukankan      html  css  js  c++  java
  • POJ 1236 Network of Schools(强连通分量)

     

    题目大意

     

    有 n(2<=n<=100) 所学校,每个学校都有个 list,列出了这个学校提供软件的学校名单。

    现在问:

            A、为了使所有的学校享用到一个软件,最少有多少学校要 copy 一个软件

            B、为了使传到任意学校的软件能够传到其他所有的学校,至少要添加多少个学校到相应学校的 list 中去

     

    做法分析

     

    这种题,显然要先给图“化简”,是其成为一个 DAG 图

    对于 task A,我们只需统计“化简”后的 DAG 中入度为 0 的点的个数

    对于 task B,其实就是求添加多少条边使得 DAG 之间的所有点能够相互到达(形成一个 SCC),有一个结论:答案是入度为 0 的点的个数和出度为 0 的点个数的最大者

     

    参考代码

     

    POJ 1236
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <vector>
     5 #include <stack>
     6 
     7 using namespace std;
     8 
     9 const int N=106;
    10 
    11 vector <int> arc[N];
    12 int dfn[N], low[N], id[N];
    13 int n, T, ind;
    14 stack <int> s;
    15 bool vs[N];
    16 
    17 void tarjan(int u)
    18 {
    19     vs[u]=1, s.push(u);
    20     dfn[u]=low[u]=T++;
    21     int len=(int)arc[u].size();
    22     for(int i=0; i<len; i++)
    23     {
    24         int v=arc[u][i];
    25         if(dfn[v]==-1)
    26         {
    27             tarjan(v);
    28             if(low[u]>low[v]) low[u]=low[v];
    29         }
    30         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
    31     }
    32     if(low[u]==dfn[u])
    33     {
    34         for(int v; 1; )
    35         {
    36             v=s.top();
    37             s.pop(), vs[v]=0;
    38             id[v]=ind;
    39             if(v==u) break;
    40         }
    41         ind++;
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%d", &n);
    48     for(int i=1, u; i<=n; i++)
    49     {
    50         arc[i].clear();
    51         while(scanf("%d", &u), u!=0) arc[i].push_back(u);
    52     }
    53     for(int i=1; i<=n; i++) dfn[i]=-1, vs[i]=0;
    54     while(!s.empty()) s.pop();
    55     ind=T=0;
    56     for(int i=1; i<=n; i++) if(dfn[i]==-1) tarjan(i);
    57     for(int i=0; i<ind; i++) dfn[i]=low[i]=0;
    58     for(int i=1; i<=n; i++)
    59     {
    60         int len=(int)arc[i].size(), u=id[i];
    61         for(int j=0; j<len; j++)
    62         {
    63             int v=id[arc[i][j]];
    64             if(u!=v) dfn[u]++, low[v]++;
    65         }
    66     }
    67     int ans1=0, ans2=0;
    68     for(int i=0; i<ind; i++)
    69     {
    70         if(low[i]==0) ans1++;
    71         if(dfn[i]==0) ans2++;
    72     }
    73     ans2=max(ans1, ans2);
    74     if(ind==1) ans1=1, ans2=0;
    75     printf("%d\n%d\n", ans1, ans2);
    76     return 0;
    77 }

    AC通道

    POJ 1236 Network of Schools

  • 相关阅读:
    AxWindowsMediaPlayer的详细用法
    C# Windows Media Player控件的常用属性及方法
    C#中winform使用相对路径读取文件的方法
    DataGridView控件在加载数据时产生的闪烁问题
    浅谈C#中的双缓冲
    几种C#实现播放声音的方法
    C#下实现软件欢迎界面
    DataGridView控件内建立日期选择编辑列
    程序员值得看的电影(20170420EDIT)
    员工照片
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2963984.html
Copyright © 2011-2022 走看看