zoukankan      html  css  js  c++  java
  • POJ1236 强连通 (缩点后度数的应用)

    题意:
          一些学校有一个发送消息的体系,现在给你一些可以直接发送消息的一些关系(单向)然后有两个问题
    (1) 问你至少向多少个学校发送消息可以让所有的学校都得到消息
    (2) 问至少加多少条边可以让所有学校达到消息互通(变成强连通图)


    思路:
          比较简单了,我们先强连通所点,然后对于第一个问题,我们只要输出入度为0的个数,这个很好理解,对于第二个问题,我们可以输出max(入度为0的个数,出度为0的个数),这样做是因为我们可以吧度数大的先用小的补充上,剩下的就随意补充就行了,还有就是记得只有一个联通分量的时候特判一下,

    PS :假如这个题目要是让输出解决方案的话也比较好弄,对于第一个,每个入度为0的点给一个,每个强连通分量《元素个数大于1的》给一个就行了。对于第二个,就是先用小的填充大的,剩下的零头随意安排。


    #include<stdio.h>
    #include<string.h>
    #include<stack>
    
    #define N_node 100 + 10
    #define N_edge 10000 + 100
    
    using namespace std;
    
    typedef struct
    {
       int to ,next;
    }STAR;
    
    typedef struct
    {
       int a ,b;
    }EDGE;
    
    EDGE edge[N_edge];
    STAR E1[N_edge] ,E2[N_edge];
    int list1[N_node] ,list2[N_node] ,tot;
    int Belong[N_node] ,Cnt;
    int mark[N_node];
    stack<int>sk;
    
    void add(int a ,int b)
    {
       E1[++tot].to = b;
       E1[tot].next = list1[a];
       list1[a] = tot;
       
       E2[tot].to = a;
       E2[tot].next = list2[b];
       list2[b] = tot;
    }
    
    void DFS1(int s)
    {
       mark[s] = 1;
       for(int k = list1[s] ;k ;k = E1[k].next)
       {
          int to = E1[k].to;
          if(mark[to]) continue;
          mark[to] = 1;
          DFS1(to);
       }
       sk.push(s);
    }
    
    void DFS2(int s)
    {
       mark[s] = 1;
       Belong[s] = Cnt;
       for(int k = list2[s] ;k ;k = E2[k].next)
       {
          int to = E2[k].to;
          if(mark[to]) continue;
          mark[to]  =1;
          DFS2(to);
       }
    }
    
    int main ()
    {
       int n ,i ,j ,a;
       while(~scanf("%d" ,&n))
       {
          memset(list1 ,0 ,sizeof(list1));
          memset(list2 ,0 ,sizeof(list2));
          tot = 1;
          int nowid = 0;
          for(i = 1 ;i <= n ;i ++)
          {
             while(scanf("%d" ,&a) && a)
             {
                add(i ,a);
                edge[++nowid].a = i;
                edge[nowid].b = a;
             }
          }
          memset(mark ,0 ,sizeof(mark));
          while(!sk.empty()) sk.pop();
          for(i = 1 ;i <= n ;i ++)
          {
             if(!mark[i]) DFS1(i);
          }
          Cnt = 0;
          memset(mark ,0 ,sizeof(mark));
          while(!sk.empty())
          {
             int xin = sk.top();
             sk.pop();
             if(mark[xin]) continue;
             Cnt ++;
             DFS2(xin);
          }
          int d1[N_node] = {0};
          int d2[N_node] = {0};
          for(i = 1 ;i <= nowid ;i ++)
          {
             int a = Belong[edge[i].a];
             int b = Belong[edge[i].b];
             if(a == b) continue;
             d1[a] ++ ,d2[b] ++;
          }
          int sum1 = 0 ,sum2 = 0;
          for(i = 1 ;i <= Cnt ;i ++)
          {
             if(!d1[i]) sum1 ++;
             if(!d2[i]) sum2 ++;
          }
          if(Cnt == 1)
          {
             printf("1
    0
    ");
             continue;
          }
          printf("%d
    " ,sum2);
          sum1 > sum2 ? printf("%d
    " ,sum1) : printf("%d
    " ,sum2);
       }
       return 0;
    }

  • 相关阅读:
    hihoCoder #1179 : 永恒游戏 (暴力枚举)
    HDU 5269 ZYB loves Xor I (二分法)
    HDU 5268 ZYB loves Score (简单模拟,水)
    acdream 1683 村民的怪癖(KMP,经典变形)
    acdream 1686 梦醒(时钟重合)
    acdream 1685 多民族王国(DFS,并查集)
    acdream 1681 跳远女王(BFS,暴力)
    HDU 5265 pog loves szh II (技巧)
    HDU 5264 pog loves szh I (字符串,水)
    HDU 1023 Train Problem II (卡特兰数,经典)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062715.html
Copyright © 2011-2022 走看看