• UVA11324 The Largest Clique —— 强连通分量 + 缩点 + DP


    题目链接:https://vjudge.net/problem/UVA-11324

    题解:

    题意:给出一张有向图,求一个结点数最大的结点集,使得任意两个结点u、v,要么u能到达v, 要么v能到达u(u和v也可以互相到达)。

    1.可知在一个强连通分量中,任意两个点都可以互相到达。那么我们就对每个强连通分量进行缩点,并记录每个分量的结点个数。

    2.缩点之后,就是一张有向无环图了,这时就转化为求:从有向无环图中找出一条权值之和最大的路径。简单的记忆化搜索即可实现。

    前向星建图 + 前向星重建:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const double EPS = 1e-8;
     15 const int INF = 2e9;
     16 const LL LNF = 2e18;
     17 const int MAXM = 5e4+10;
     18 const int MAXN = 1e3+10;
     19 
     20 struct Edge
     21 {
     22     int to, next;
     23 }edge[MAXM], edge0[MAXM];   //edge为初始图, edge0为重建图
     24 int tot, head[MAXN], tot0, head0[MAXN];
     25 
     26 int Index, dfn[MAXN], low[MAXN];
     27 int top, Stack[MAXN], instack[MAXN];
     28 int scc, belong[MAXN], num[MAXN];
     29 int dp[MAXN];
     30 
     31 void addedge(int u, int v, Edge edge[], int head[], int &tot)
     32 {
     33     edge[tot].to = v;
     34     edge[tot].next = head[u];
     35     head[u] = tot++;
     36 }
     37 
     38 void Tarjan(int u)
     39 {
     40     dfn[u] = low[u] = ++Index;
     41     Stack[top++] = u;
     42     instack[u] = true;
     43     for(int i = head[u]; i!=-1; i = edge[i].next)
     44     {
     45         int v = edge[i].to;
     46         if(!dfn[v])
     47         {
     48             Tarjan(v);
     49             low[u] = min(low[u], low[v]);
     50         }
     51         else if(instack[v])
     52             low[u] = min(low[u], dfn[v]);
     53     }
     54 
     55     if(dfn[u]==low[u])
     56     {
     57         int v;
     58         scc++;
     59         do
     60         {
     61             v = Stack[--top];
     62             instack[v] = false;
     63             belong[v] = scc;
     64             num[scc]++;
     65         }while(v!=u);
     66     }
     67 }
     68 
     69 int dfs(int u)
     70 {
     71     if(dp[u]!=-1) return dp[u];
     72     dp[u] = num[u];
     73     for(int i = head0[u]; i!=-1; i = edge0[i].next)
     74     {
     75         int v = edge0[i].to;
     76         dp[u] = max(dp[u], num[u]+dfs(v));
     77     }
     78     return dp[u];
     79 }
     80 
     81 void init()
     82 {
     83     tot = tot0 = 0;
     84     memset(head, -1, sizeof(head));
     85     memset(head0, -1, sizeof(head0));
     86 
     87     Index = top = 0;
     88     memset(dfn, 0, sizeof(dfn));
     89     memset(low, 0, sizeof(low));
     90     memset(instack, 0, sizeof(instack));
     91 
     92     scc = 0;
     93     memset(num, 0, sizeof(num));
     94     memset(dp, -1, sizeof(dp));
     95 }
     96 
     97 int main()
     98 {
     99     int n, m, T;
    100     scanf("%d", &T);
    101     while(T--)
    102     {
    103         scanf("%d%d", &n, &m);
    104         init();
    105         for(int i = 1; i<=m; i++)
    106         {
    107             int u, v;
    108             scanf("%d%d", &u, &v);
    109             addedge(u, v, edge, head, tot);
    110         }
    111 
    112         for(int i = 1; i<=n; i++)
    113             if(!dfn[i])
    114                 Tarjan(i);
    115 
    116         for(int u = 1; u<=n; u++)   //重建建图
    117         for(int i = head[u]; i!=-1; i = edge[i].next)
    118         {
    119             int tmpu = belong[u];
    120             int tmpv = belong[edge[i].to];
    121             if(tmpu!=tmpv)
    122                 addedge(tmpu, tmpv, edge0, head0, tot0);
    123         }
    124 
    125         int ans = 0;
    126         for(int i = 1; i<=scc; i++)
    127             if(dp[i]==-1)
    128                 ans = max(ans, dfs(i));
    129 
    130         printf("%d
    ", ans);
    131     }
    132 }
    View Code

    前向星建图 + vector重建:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const double EPS = 1e-8;
     15 const int INF = 2e9;
     16 const int MAXM = 5e4+10;
     17 const int MAXN = 1e3+10;
     18 
     19 struct Edge
     20 {
     21     int to, next;
     22 }edge[MAXM];
     23 int tot, head[MAXN];
     24 vector<int>g[MAXN];
     25 
     26 int Index, dfn[MAXN], low[MAXN];
     27 int top, Stack[MAXN], instack[MAXN];
     28 int scc, belong[MAXN], num[MAXN];
     29 int dp[MAXN];
     30 
     31 void addedge(int u, int v)
     32 {
     33     edge[tot].to = v;
     34     edge[tot].next = head[u];
     35     head[u] = tot++;
     36 }
     37 
     38 void Tarjan(int u)
     39 {
     40     dfn[u] = low[u] = ++Index;
     41     Stack[top++] = u;
     42     instack[u] = true;
     43     for(int i = head[u]; i!=-1; i = edge[i].next)
     44     {
     45         int v = edge[i].to;
     46         if(!dfn[v])
     47         {
     48             Tarjan(v);
     49             low[u] = min(low[u], low[v]);
     50         }
     51         else if(instack[v])
     52             low[u] = min(low[u], dfn[v]);
     53     }
     54 
     55     if(dfn[u]==low[u])
     56     {
     57         int v;
     58         scc++;
     59         do
     60         {
     61             v = Stack[--top];
     62             instack[v] = false;
     63             belong[v] = scc;
     64             num[scc]++;
     65         }while(v!=u);
     66     }
     67 }
     68 
     69 int dfs(int u)
     70 {
     71     if(dp[u]!=-1) return dp[u];
     72     dp[u] = num[u];
     73     for(int i = 0; i<g[u].size(); i++)
     74     {
     75         int v = g[u][i];
     76         dp[u] = max(dp[u], num[u]+dfs(v));
     77     }
     78     return dp[u];
     79 }
     80 
     81 void init(int n)
     82 {
     83     tot = 0;
     84     memset(head, -1, sizeof(head));
     85 
     86     Index = top = 0;
     87     memset(dfn, 0, sizeof(dfn));
     88     memset(low, 0, sizeof(low));
     89     memset(instack, 0, sizeof(instack));
     90 
     91     scc = 0;
     92     memset(num, 0, sizeof(num));
     93     memset(dp, -1, sizeof(dp));
     94     for(int i = 1; i<=n; i++)
     95         g[i].clear();
     96 }
     97 
     98 int main()
     99 {
    100     int n, m, T;
    101     scanf("%d", &T);
    102     while(T--)
    103     {
    104         scanf("%d%d", &n, &m);
    105         init(n);
    106         for(int i = 1; i<=m; i++)
    107         {
    108             int u, v;
    109             scanf("%d%d", &u, &v);
    110             addedge(u, v);
    111         }
    112 
    113         for(int i = 1; i<=n; i++)
    114             if(!dfn[i])
    115                 Tarjan(i);
    116 
    117         for(int u = 1; u<=n; u++)
    118         for(int i = head[u]; i!=-1; i = edge[i].next)
    119         {
    120             int tmpu = belong[u];
    121             int tmpv = belong[edge[i].to];
    122             if(tmpu!=tmpv)
    123                 g[tmpu].push_back(tmpv);
    124         }
    125 
    126         int ans = 0;
    127         for(int i = 1; i<=scc; i++)
    128             if(dp[i]==-1)
    129                 ans = max(ans, dfs(i));
    130 
    131         printf("%d
    ", ans);
    132     }
    133 }
    View Code

    vector建图 + vector重建:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const double EPS = 1e-8;
     15 const int INF = 2e9;
     16 const int MAXN = 1e3+10;
     17 
     18 vector<int>G[MAXN], g[MAXN];
     19 
     20 int Index, dfn[MAXN], low[MAXN];
     21 int top, Stack[MAXN], instack[MAXN];
     22 int scc, belong[MAXN], num[MAXN];
     23 int dp[MAXN];
     24 
     25 void Tarjan(int u)
     26 {
     27     dfn[u] = low[u] = ++Index;
     28     Stack[top++] = u;
     29     instack[u] = true;
     30     for(int i = 0; i<G[u].size(); i++)
     31     {
     32         int v = G[u][i];
     33         if(!dfn[v])
     34         {
     35             Tarjan(v);
     36             low[u] = min(low[u], low[v]);
     37         }
     38         else if(instack[v])
     39             low[u] = min(low[u], dfn[v]);
     40     }
     41 
     42     if(dfn[u]==low[u])
     43     {
     44         int v;
     45         scc++;
     46         do
     47         {
     48             v = Stack[--top];
     49             instack[v] = false;
     50             belong[v] = scc;
     51             num[scc]++;
     52         }while(v!=u);
     53     }
     54 }
     55 
     56 int dfs(int u)
     57 {
     58     if(dp[u]!=-1) return dp[u];
     59     dp[u] = num[u];
     60     for(int i = 0; i<g[u].size(); i++)
     61     {
     62         int v = g[u][i];
     63         dp[u] = max(dp[u], num[u]+dfs(v));
     64     }
     65     return dp[u];
     66 }
     67 
     68 void init(int n)
     69 {
     70     Index = top = 0;
     71     memset(dfn, 0, sizeof(dfn));
     72     memset(low, 0, sizeof(low));
     73     memset(instack, 0, sizeof(instack));
     74 
     75     scc = 0;
     76     memset(num, 0, sizeof(num));
     77     memset(dp, -1, sizeof(dp));
     78     for(int i = 1; i<=n; i++)
     79     {
     80         G[i].clear();
     81         g[i].clear();
     82     }
     83 }
     84 
     85 int main()
     86 {
     87     int n, m, T;
     88     scanf("%d", &T);
     89     while(T--)
     90     {
     91         scanf("%d%d", &n, &m);
     92         init(n);
     93         for(int i = 1; i<=m; i++)
     94         {
     95             int u, v;
     96             scanf("%d%d", &u, &v);
     97             G[u].push_back(v);
     98         }
     99 
    100         for(int i = 1; i<=n; i++)
    101             if(!dfn[i])
    102                 Tarjan(i);
    103 
    104         for(int u = 1; u<=n; u++)
    105         for(int i = 0; i<G[u].size(); i++)
    106         {
    107             int tmpu = belong[u];
    108             int tmpv = belong[G[u][i]];
    109             if(tmpu!=tmpv)
    110                 g[tmpu].push_back(tmpv);
    111         }
    112 
    113         int ans = 0;
    114         for(int i = 1; i<=scc; i++)
    115             if(dp[i]==-1)
    116                 ans = max(ans, dfs(i));
    117 
    118         printf("%d
    ", ans);
    119     }
    120 }
    View Code
  • 相关阅读:
    目标检测评价指标
    DALSA相机SDK不完全教程
    windows 安装pycocotools
    keras第二课:后端函数
    Python中os.mkdir()与os.makedirs()的区别
    ARM知识
    神经网络结构
    PIL 中的 Image 模块
    Matplotlib使用
    keras第一课:Cifar分类
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7820041.html
Copyright © 2020-2023  润新知