• loj 1210 (求最少的加边数使得图变成强连通)


    题目链接:http://lightoj.com/volume_showproblem.php?problem=1210

    思路:首先是缩点染色,然后重建并且统计新图中的每个点的入度和出度,于是答案就是max(入度为0的点的个数, 出度为0的点的个数,这里有一个trick就是如果scc_count == 1,那么应该输出0.

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <stack>
      6 using namespace std;
      7 
      8 const int MAXN = (20000 + 20);
      9 int n, m, NE;
     10 struct Edge {
     11     int v, next;
     12 } edge[MAXN << 2];
     13 
     14 int head[MAXN];
     15 void Insert(int u, int v)
     16 {
     17     edge[NE].v = v;
     18     edge[NE].next = head[u];
     19     head[u] = NE++;
     20 }
     21 
     22 int cnt, scc_count;
     23 int low[MAXN], dfn[MAXN], color[MAXN];
     24 bool mark[MAXN];
     25 stack<int >S;
     26 
     27 void Tarjan(int u)
     28 {
     29     low[u] = dfn[u] = ++cnt;
     30     mark[u] = true;
     31     S.push(u);
     32     for (int i = head[u]; i != -1; i = edge[i].next) {
     33         int v = edge[i].v;
     34         if (dfn[v] == 0) {
     35             Tarjan(v);
     36             low[u] = min(low[u], low[v]);
     37         } else if (mark[v]) {
     38             low[u] = min(low[u], dfn[v]);
     39         }
     40     }
     41     if (low[u] == dfn[u]) {
     42         scc_count++;
     43         int v;
     44         do {
     45             v = S.top();
     46             S.pop();
     47             mark[v] = false;
     48             color[v] = scc_count;
     49         } while (u != v);
     50     }
     51 }
     52 
     53 int Indegree[MAXN], Outdegree[MAXN];
     54 
     55 int main()
     56 {
     57     int _case, t = 1;
     58     scanf("%d", &_case);
     59     while (_case--) {
     60         scanf("%d %d", &n, &m);
     61         NE = 0;
     62         memset(head, -1, sizeof(head));
     63         while (m--) {
     64             int u, v;
     65             scanf("%d %d", &u, &v);
     66             Insert(u, v);
     67         }
     68         cnt = scc_count = 0;
     69         memset(dfn, 0, sizeof(dfn));
     70         memset(mark, false, sizeof(mark));
     71         for (int i = 1; i <= n; i++) {
     72             if (dfn[i] == 0) Tarjan(i);
     73         }
     74         memset(Indegree, 0, sizeof(Indegree));
     75         memset(Outdegree, 0, sizeof(Outdegree));
     76         for (int u = 1; u <= n; u++) {
     77             for (int i = head[u]; i != -1; i = edge[i].next) {
     78                 int v = edge[i].v;
     79                 if (color[u] != color[v]) {
     80                     Indegree[color[v]]++;
     81                     Outdegree[color[u]]++;
     82                 }
     83             }
     84         }
     85         int ans1 = 0, ans2 = 0;
     86         for (int i = 1; i <= scc_count; i++) {
     87             if (Indegree[i] == 0) ans1++;
     88             if (Outdegree[i] == 0) ans2++;
     89         }
     90         printf("Case %d: ", t++);
     91         if (scc_count == 1) {
     92             puts("0");
     93         } else 
     94             printf("%d
    ", max(ans1, ans2));
     95     }
     96     return 0;
     97 }
     98 
     99 
    100         
    View Code
  • 相关阅读:
    C/C++的区别
    stm32之UCOS-III
    PID控制及整定算法
    PCB设计基础及技巧
    电路的一些基本理论
    stm32与三菱PLC通信
    stm32之外设控制
    stm32之内部功能
    JavaScript数组方法详解
    git新建关联克隆仓库指令
  • 原文地址:https://www.cnblogs.com/wally/p/3529842.html
Copyright © 2020-2023  润新知