• Aiiage Camp Day5 A Rikka with Linker


    题意

      n个点,m个关系。a依赖b则a需要出现在b前。

      求满足所有关系的最短序列长度。

      n<18, m<n(n-1)

    题解

      问题事实上等价于有向有环图的拓扑排序。

      所以用拓扑排序结合搜索有个显然的2^n*n^2的做法。

      赛场上写的有点丑T了。

      标算是DP。F[S]表示添加了集合S的最短长度。对于每个S,枚举添加点x:若x被依赖的所有点都出现过,则只需要在当前序列最后添加x;否则,需要在最后再添加一个x使尚未添加的点满足条件。

      复杂度O(2^n*n)。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int h[30], f[300000];
     5 
     6 int main()
     7 {
     8     int T;
     9     for (scanf("%d", &T); T; T--)
    10     {
    11         memset(h, 0, sizeof(h));
    12         int n, m;
    13         scanf("%d%d", &n, &m);
    14         for (int i = 0; i < m; ++i)
    15         {
    16             int u, v;
    17             scanf("%d%d", &u, &v);
    18             h[v] ^= 1 << (u - 1);
    19         }
    20         int maxx(pow(2, n));
    21         for (int i = 0; i < maxx; ++i)
    22             f[i] = 2 * n;
    23         f[0] = 0;
    24         for (int i = 0; i < maxx; ++i)
    25             for (int j = 1; j <= n; ++j)
    26                 if (!(i & (1 << (j - 1))))
    27                     if ((h[j] ^ i) & h[j])
    28                         f[i ^ (1 << (j - 1))] = min(f[i ^ (1 << (j - 1))], f[i] + 2);
    29                     else
    30                         f[i ^ (1 << (j - 1))] = min(f[i ^ (1 << (j - 1))], f[i] + 1);
    31         printf("%d
    ", f[maxx - 1]);
    32     }
    33     
    34     return 0;
    35 }
  • 相关阅读:
    webstorm2018.1 汉化
    微信小程序转发微信小程序转发
    微信小程序下拉刷新和上拉加载的实现
    微信小程序基本目录结构学习
    JavaScript中闭包的写法和作用详解
    前端面试 问题汇总
    js 循环
    vue.js的手脚架vue-cli项目搭建的步骤
    js 条件判断
    数组
  • 原文地址:https://www.cnblogs.com/aseer/p/8479842.html
Copyright © 2020-2023  润新知