JZOJ4555【NOI2016模拟6.20】没有强联通分量的无聊世界 利用Dag性质的简单Dp

来源:互联网 发布:淘宝卖家加分规则 编辑:程序博客网 时间:2024/06/05 16:30

题目大意

现在有一个N个点M条边的有向图,问最少减去多少条边使得这个有向图无有向环。

N22
MN(N1)2

解题思路

不存在有向环,即操作后的图要是一幅Dag。回想一下Dag的性质,即只能拓扑序小的向拓扑序大的点连边。那么我们设F[s]表示状态为s(一个二进制)的点形成一个Dag能加入边数的最大值。我们再枚举下一个加入的点,然后边数加上这个点和Dag中已有的点间的边的数量。最后有MF2N11就是答案。

程序

//YxuanwKeith#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 25, MAXM = (1 << 25) + 5;int N, M, R[MAXN], F[MAXM];int main() {    freopen("data.in", "r", stdin), freopen("data.out", "w", stdout);    scanf("%d%d", &N, &M);    for (int i = 1; i <= M; i ++) {        int u, v;        scanf("%d%d", &u, &v);        R[u] = R[u] | (1 << (v - 1));    }    memset(F, 200, sizeof F);    F[0] = 0;    int Lim = (1 << N) - 1;    for (int i = 0; i < Lim; i ++) {        for (int j = 1; j <= N; j ++) {            int Num = 1 << (j - 1);            if (i & Num) continue;            F[i | Num] = max(F[i | Num], F[i] + __builtin_popcount(R[j] & i));        }    }     printf("%d\n", M - F[Lim]);}
1 0
原创粉丝点击