zoukankan      html  css  js  c++  java
  • poj 1236 Network of Schools : 求需要添加多少条边成为强连通图 tarjan O(E)

      1 /**
      2 problem: http://poj.org/problem?id=1236
      3 
      4 缩点后入度为0的点的总数为需要发放软件的学校个数
      5 缩点后出度为0的点的总数和入度为0的点的总数的最大值为需要增加的传输线路的条数(头尾相接)
      6 特别的,当图为强连通图时,发放软件的学校个数为1, 增加线路为0
      7 **/
      8 #include<stdio.h>
      9 #include<stack>
     10 #include<algorithm>
     11 using namespace std;
     12 
     13 class Graphics{
     14     const static int MAXN = 105;
     15     const static int MAXM = 100005;
     16 private:
     17     struct Edge{
     18         int to, next;
     19         bool bridge;
     20     }edge[MAXM];
     21     struct Point{
     22         int dfn, low, color;
     23     }point[MAXN];
     24     int sign, dfnNum, colorNum, sumOfPoint, first[MAXN];
     25     bool vis[MAXN];
     26     stack<int> stk;
     27     void tarjan(int u){
     28         point[u].dfn = ++dfnNum;
     29         point[u].low = dfnNum;
     30         vis[u] = true;
     31         stk.push(u);
     32         for(int i = first[u]; i != -1; i = edge[i].next){
     33             int to = edge[i].to;
     34             if(!point[to].dfn){
     35                 tarjan(to);
     36                 point[u].low = min(point[to].low, point[u].low);
     37                 if(point[to].low > point[u].dfn){
     38                     edge[i].bridge = true;
     39                 }
     40             }else if(vis[to]){
     41                 point[u].low = min(point[to].dfn, point[u].low);
     42             }
     43         }
     44         if(point[u].dfn == point[u].low){
     45             vis[u] = false;
     46             point[u].color = ++colorNum;
     47             while(stk.top() != u){
     48                 vis[stk.top()] = false;
     49                 point[stk.top()].color = colorNum;
     50                 stk.pop();
     51             }
     52             stk.pop();
     53         }
     54     }
     55 public:
     56     void clear(int n){
     57         sign = dfnNum = colorNum = 0;
     58         for(int i = 1; i <= n; i ++){
     59             first[i] = -1;
     60             vis[i] = 0;
     61         }
     62         sumOfPoint = n;
     63         while(!stk.empty()) stk.pop();
     64     }
     65     void addEdgeOneWay(int u, int v){
     66         edge[sign].to = v;
     67         edge[sign].bridge = false;
     68         edge[sign].next = first[u];
     69         first[u] = sign ++;
     70     }
     71     void addEdgeTwoWay(int u, int v){
     72         addEdgeOneWay(u, v);
     73         addEdgeOneWay(v, u);
     74     }
     75     void tarjanAllPoint(){
     76         for(int i = 1; i <= sumOfPoint; i ++){
     77             if(!point[i].dfn)
     78                 tarjan(i);
     79         }
     80     }
     81     pair<int, int> getAns(){
     82         int ans = 0, ans2 = 0;
     83         int *indegree = new int[sumOfPoint+1];
     84         int *outdegree = new int[sumOfPoint+1];
     85         for(int i = 1; i <= sumOfPoint; i ++){
     86             indegree[i] = 0;
     87             outdegree[i] = 0;
     88         }
     89         tarjanAllPoint();
     90         for(int i = 1; i <= sumOfPoint; i ++){
     91             for(int j = first[i]; j != -1; j = edge[j].next){
     92                 int to = edge[j].to;
     93                 if(point[to].color != point[i].color){
     94                     outdegree[point[i].color] ++;
     95                     indegree[point[to].color] ++;
     96                 }
     97             }
     98         }
     99         for(int i = 1; i <= colorNum; i ++){
    100             if(!indegree[i]){
    101                 ans ++;
    102             }
    103             if(!outdegree[i]){
    104                 ans2 ++;
    105             }
    106         }
    107         delete []indegree; delete []outdegree;
    108         if(colorNum == 1){
    109             return make_pair(1, 0);
    110         }else{
    111             return make_pair(ans, max(ans, ans2));
    112         }
    113     }
    114 }graph;
    115 
    116 int main(){
    117     int n;
    118     scanf("%d", &n);
    119     graph.clear(n);
    120     for(int i = 1; i <= n; i ++){
    121         int a;
    122         while(scanf("%d", &a) && a){
    123             graph.addEdgeOneWay(i, a);
    124         }
    125     }
    126     pair<int, int> ans = graph.getAns();
    127     printf("%d
    %d
    ", ans.first, ans.second);
    128     return 0;
    129 }

     ps:

    这两句话是不一样的,在有向图中存在非环边还是非桥的情况

  • 相关阅读:
    Vue中使用WebSocket
    中断「interrupt」(IPI interrupt)
    ARM instruction misc
    ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(2)- 寄存器
    android logd 原理及实现
    [FTRACE] vmlinux __mcount_loc section
    如何计算eMMC大小
    get the emmc capacity in kernel
    uboot misc
    GPT分区表详解
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10533860.html
Copyright © 2011-2022 走看看