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:

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

  • 相关阅读:
    PostgreSQL中的partition-wise join
    Partition-wise join
    外观模式 门面模式 Facade 结构型 设计模式(十三)
    桥接模式 桥梁模式 bridge 结构型 设计模式(十二)
    组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)
    创建型设计模式对比总结 设计模式(八)
    原型模式 prototype 创建型 设计模式(七)
    单例模式 创建型 设计模式(六)
    建造者模式 生成器模式 创建型 设计模式(五)
    抽象工厂模式 创建型 设计模式(四)
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10533860.html
Copyright © 2011-2022 走看看