• ACM-ICPC 2017 南宁赛区现场赛 M. The Maximum Unreachable Node Set(二分图)


    题目链接:https://nanti.jisuanke.com/t/19979

    题意:给出一个 n 个点,m 条边的 DAG,选出最大的子集使得其中结点两两不能到达。

    题解:参考自:https://blog.csdn.net/winter2121/article/details/79849472

          首先用弗洛伊德跑出一个可达性矩阵,然后从每个点开始 dfs 跑二分图,则最后 dfs 出的路径为若干条链,而对于链显然除了最后一个结点,其他结点都要删除,而其他结点的总数即跑二分图的匹配数,用总数减去即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define mst(a,b) memset((a),(b),sizeof(a))
     6 #define mp(a,b) make_pair(a,b)
     7 #define pi acos(-1)
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 const int INF = 0x3f3f3f3f;
    11 const double eps = 1e-6;
    12 const int MAXN = 1e5 + 10;
    13 const int MAXM = 2e6 + 10;
    14 
    15 int n,m;
    16 int g[110][110],fa[110];
    17 bool vis[110];
    18 
    19 bool dfs(int u) {
    20     for(int i = 1; i <= n; i++) {
    21         if(g[u][i] && !vis[i]) {
    22             vis[i] = true;
    23             if(fa[i] == 0 || dfs(fa[i])) {
    24                 fa[i] = u;
    25                 return true;
    26             }
    27         }
    28     }
    29     return false;
    30 }
    31 
    32 int main() {
    33 #ifdef local
    34     freopen("data.txt", "r", stdin);
    35 //    freopen("data.txt", "w", stdout);
    36 #endif
    37     int t;
    38     scanf("%d",&t);
    39     while(t--) {
    40         scanf("%d%d",&n,&m);
    41         for(int i = 1; i <= n; i++) {
    42             fa[i] = 0;
    43             for(int j = 1; j <= n; j++) g[i][j] = 0;
    44         }
    45         while(m--) {
    46             int u,v;
    47             scanf("%d%d",&u,&v);
    48             g[u][v] = 1;
    49         }
    50         for(int k = 1; k <= n; k++)
    51             for(int i = 1; i <= n; i++)
    52                 for(int j = 1; j <= n; j++)
    53                     g[i][j] |= g[i][k] & g[k][j];
    54         int res = 0;
    55         for(int i = 1; i <= n; i++) {
    56             mst(vis, 0);
    57             if(dfs(i)) res++;
    58         }
    59         printf("%d
    ",n - res);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    工程思维
    小骆驼 第三章 列表与数组
    小骆驼 第二章 标量数据
    小骆驼 第二章 标量数据
    小骆驼 第二章 标量数据
    split和join合写
    Competition and Predation
    What is the difference between Θ(n) and O(n)?
    数学基础之概率统计
    enumerate()函数
  • 原文地址:https://www.cnblogs.com/scaulok/p/9704050.html
Copyright © 2020-2023  润新知