zoukankan      html  css  js  c++  java
  • POJ 1236 【强连通图+缩点】.cpp

    题意:

      给出n个学校的兄弟学校..<单方面认为>

      如果给了一个软件给某个学校..他就会把这个软件给他的兄弟学校..

      然后求两个解:

        1st: 至少准备多少个软件..可以使所有的学校都有这个软件..

        2nd:至少加多少条边..可以使只给一个软件..就能让所有学校都得到这个软件..

    输入:

      一个n 代表有n个学校..

      接下来n行..

      第i行 给出第i个学校的兄弟学校(单方面认为)的列表..以0结束..

     

      输出两个解的结果..

     

    思路:

    缩点之后把原图变成一个有向无环图..

     

      两个解可以看成是:

      1st:把该有向无环图看成一个森林..求的就是有多少棵树..<即入度为0的根节点的个数>

      2nd: 求加多少条边可以使森林变成强连通图..

        自己画图可以看出..找出入度为0和出度为0中最大的个数..即为要连的边..

        因为如果入度为0比出度为0少..则从入度为0的点往出度为0的点连边..

        可以使之变成一个强连通分量..

     

    Tips:

      ※:求入度和出度的时候..可以直接遍历缩点后的图然后求..

      ※: 注意求第二个解的时候..如果缩点后的图已经是强连通分量..则不用加边..

        但是理论上求出来的入度为0和出度为0的个数都会是 1

        所以要特别判断一下..

    Code:

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 const int INF = 0x1f1f1f1f;
      6 #define clr(x) memset(x, 0, sizeof(x))
      7 const int MAXN = 110;
      8 
      9 struct Edge
     10 {
     11     int to;
     12     int next;
     13 }edge[10000010];
     14 int head[MAXN];
     15 int tot;
     16 
     17 void add(int s, int u)
     18 {
     19     edge[tot].to = u;
     20     edge[tot].next = head[s];
     21     head[s] = tot++;
     22 }
     23 
     24 int dfn[MAXN], low[MAXN];
     25 int ins[MAXN], sta[MAXN], col[MAXN];
     26 int ti, top, cnt;
     27 int n;
     28 
     29 void tarjan(int u)
     30 {
     31     int i, k;
     32     dfn[u] = low[u] = ++ti;
     33     ins[u] = 1;
     34     sta[++top] = u;
     35     for(i = head[u]; i != -1; i = edge[i].next) {
     36         k = edge[i].to;
     37         if(dfn[k] == 0) {
     38             tarjan(k);
     39             low[u] = min(low[u], low[k]);
     40         } else if(ins[k]) {
     41             low[u] = min(low[u], dfn[k]);
     42         }
     43     }
     44     if(dfn[u] == low[u]) {
     45         cnt++;
     46         do
     47         {
     48             k = sta[top--];
     49             col[k] = cnt;
     50             ins[k] = 0;
     51         }while(u != k);
     52     }
     53 
     54 }
     55 
     56 void solve_ta()
     57 {
     58     int i, k;
     59     ti = top = cnt = 0;
     60     clr(dfn);
     61     for(i = 1; i <= n; ++i)
     62         if(!dfn[i])
     63             tarjan(i);
     64 }
     65 
     66 int ansa, ansb;
     67 int in[MAXN], out[MAXN];
     68 void solve()
     69 {
     70     int i, j, k;
     71     ansa = ansb = 0;
     72     clr(in), clr(out);
     73     solve_ta();
     74 
     75     for(i = 1; i <= n; ++i) {
     76         for(j = head[i]; j != -1; j = edge[j].next) {
     77             k = edge[j].to;
     78             if(col[i] != col[k]) {
     79                 in[col[k]]++;
     80                 out[col[i]]++;
     81             }
     82         }
     83     }
     84 
     85     int tmpa = 0, tmpb = 0;
     86     for(i = 1; i <= cnt; ++i) {
     87         if(in[i] == 0) tmpa++;
     88         if(out[i] == 0) tmpb++;
     89     }
     90 
     91     ansa = tmpa;
     92     ansb = max(tmpa, tmpb);
     93     if(cnt == 1) ansb = 0;
     94 }
     95 
     96 int main()
     97 {
     98     int i, j, k;
     99     int a, b, w;
    100     while(scanf("%d", &n) != EOF)
    101     {
    102         tot = 0;
    103         memset(head, 0xff, sizeof(head));
    104 
    105         for(i = 1; i <= n; ++i) {
    106             while(scanf("%d", &a), a) {
    107                 add(i, a);
    108             }
    109         }
    110 
    111         solve();
    112         printf("%d\n%d\n", ansa, ansb);
    113     }
    114     return 0;
    115 }

     

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

  • 相关阅读:
    mvc control 请求两次问题
    Jquery跨域获得Json
    使用ajax跨域withCredentials的作用
    以下是关于ASP.NET中保存各种信息的对象的比较,理解这些对象的原理,对制作完善的程序来说是相当有必要的(摘至互联网,并非原创--xukunping)
    【算法】字符串近似搜索(转)
    字符串相似度算法(编辑距离算法 Levenshtein Distance)(转)
    图像相似度算法的C#实现及测评
    求时间差的sql语句。 比如如下数据
    微信公众平台开发之微信access_token如何有效长期保存
    PowerDesigner打开设计文件后提示failed to read the fileXXX的解决办法
  • 原文地址:https://www.cnblogs.com/Griselda/p/2711761.html
Copyright © 2011-2022 走看看