zoukankan      html  css  js  c++  java
  • HDU 4862 Jump 任意起点最大权K链不相交覆盖

    你可以从任意起点开始起跳最多K次

    每次跳你可以选择往右或者往下跳 从(x1,y1)跳到(x2,y2) 消耗的能量是曼哈顿距离-1

    但是如果每次跳的起点和终点格子里的数字是相同的为X的话你会得到X能量

    问你跳K次能不能把整个图刚好跳完(每个点被经过一次) 如果可以的话输出能量的最大值

    解:和最小链覆盖一样先把每个点拆成入点和出点 左边是出点 右边是入点 然后按照题意建好边

    重要的是我们怎么限制最多起跳K次这个条件 解决方法是Add(S,S',K,0) 然后S'朝右边每个点连一条容量为1费用为0的边

    为什么这样就是最多K条链呢?考虑最小链覆盖=|V|-匹配数 即匹配完后 右边没有被匹配的点(入点)是要被当作一条链的起点的 所以右边有几个没被匹配的点就要有几条链

    所以我们限制右边最多只能有K个节点没被匹配到即可

    #include<bits/stdc++.h>
    #define reg register
    using namespace std;
    typedef long long ll;
    typedef int JQK;
    const int INF = 0x7f7f7f7f;
    const int MAXN = 505, MAXM = 13000;
    int Head[MAXN], cur[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1;
    int S, T, MAXP, MAXF, pre[MAXN];
    JQK lev[MAXN], mono[MAXM << 1];
    bool exist[MAXN];
    inline void RR(int &x) {
            char c;
            bool sign = false;
            for (c = getchar(); c < '0' || c > '9'; c = getchar())
                    if (c == '-') {
                            sign = true;
                    }
            for (x = 0; c >= '0' && c <= '9'; c = getchar()) {
                    x = x * 10 + c - '0';
            }
            sign && (x = -x);
    }char f1[15][15];
    int ff[15][15];
    int num[15][15];
    int main() {
            int TNT;
            int n, m, K;
            RR(TNT);
            for (int cas = 1; cas <= TNT; cas++) {
                    int sum = 0;
                    RR(n), RR(m), RR(K);
                    for (int i = 1; i <= n; i++) {
                            scanf("%s", f1[i] + 1);
                            for (int j = 1; j <= m; j++) {
                                    ff[i][j] = f1[i][j] - '0';
                            }
                    }
                    for (int i = 1; i <= n; i++) {
                            for (int j = 1; j <= m; j++) {
                                    num[i][j] = ++sum;
                            }
                    }
                    MAXP = 2 * sum + 3;
                    init(2 * sum + 2, 2 * sum + 3);
                    addedge(S, S - 1, K, 0);
                    for (int i = 1; i <= n; i++) {
                            for (int j = 1; j <= m; j++) {
                                    addedge(S, num[i][j], 1, 0);
                                    addedge(sum + num[i][j], T, 1, 0);
                                    addedge(S - 1, sum + num[i][j], 1, 0);
                            }
                    }
                    for (int i = 1; i <= n; i++) {
                            for (int j = 1; j <= m; j++) {
                                    int now = ff[i][j];
                                    for (int k = i + 1; k <= n; k++) {
                                            int now2 = ff[k][j];
                                            int add = (now == now2) ? now : 0;
                                            addedge(num[i][j], sum + num[k][j], 1, -(add - (k - i - 1)));
                                    }
                                    for (int k = j + 1; k <= m; k++) {
                                            int now2 = ff[i][k];
                                            int add = (now == now2) ? now : 0;
                                            addedge(num[i][j], sum + num[i][k], 1, -(add - (k - j - 1)));
                                    }
                            }
                    }
                    printf("Case %d : ", cas);
                    if (K < min(n, m)) {
                            printf("-1
    ");
                            continue;
                    }
                    int anser = MCMF();
                    if (MAXF != sum) {
                            printf("-1
    ");
                    } else {
                            printf("%d
    ", -anser);
                    }
            }
            return 0;
    }

     

  • 相关阅读:
    转载 NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel
    Microsoft Visual SourceSafe 6.0 无法关联项目
    dynamic json
    c#查找string数组的某一个值的索引
    C#中 删除掉字符串数组中的空字符串
    c# 比较两个数组每一个值是否相等
    c#比较两个数组的差异
    C#动态操作DataTable(新增行、列、查询行、列等)
    C#数字转字母,ASCII码转换
    c#中使程序跳到指定行中
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11756434.html
Copyright © 2011-2022 走看看