HDU6094 Rikka with K-Match

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU6094 Rikka with K-Match相关的知识,希望对你有一定的参考价值。

Rikka with K-Match

Yuta has a graph (G) with (n) nodes ((i,j)(1 leq i leq n,1 leq j leq m)). There is an edge between ((a,b)) and ((c,d)) if and only if (|a-c|+|b-d|=1). Each edge has its weight.

Now Yuta wants to calculate the minimum weight (K)-matching of (G).

(1 leq n leq 4 imes 10^4,1 leq m leq 4)

题解

https://blog.csdn.net/The_star_is_at/article/details/76919415

应该是一个经典的 Idea 了。令 (w_i) 为匹配数为 (i) 时的最小匹配,那么因为匹配是一个费用流问题,所以一定有 (w_{i+1}-w_{i} geq w_{i}-w_{i-1})

考虑把 (w_i) 看成平面上的点 ((i,w_i)),那么显然所有点都分布在一个下凸壳上,因此肯定存在一个斜率 (d),使得这个斜率的直线与下凸壳的切点恰好为 ((K,w_K)),即 ((K,w_K))(w_i-id) 最小的点,这相当于把边权减去 (d) 后的最小匹配。

因此可以二分斜率 (d),然后求出边权全部减去 (d) 后的最小匹配的值以及最小匹配中有多少条边,根据最小匹配中的边数和 (K) 的大小关系来决定二分的方向。这样问题就转化成了求 (O(log n)) 次网格图最大匹配。这是一个轮廓线 DP 的经典问题,可以在 (O(nm2^m)) 内解决。

因此总的时间复杂度为 (O(nm2^mlog n))

要注意的是二分上界不能设为 (10^9) 级别,考虑一条 (1)(10^9) 交错的链,那么在最后一次增广的时候所有的 (1) 都会变成 (10^9),因此二分上界应该是 (10^9 imes frac{nm}{2}),标程把上界设为了 (10^{14}),DP 时刚好不会爆 long long

CO int64 inf=1e18;
int n,m,A[40001][4],B[40001][4];
int64 f[2][5][1<<4];int g[2][5][1<<4];

pair<int64,int> solve(int64 mid){
    for(int i=0;i<=m;++i) fill(f[0][i],f[0][i]+(1<<m),inf);
    f[0][m][(1<<m)-1]=g[0][m][(1<<m)-1]=0;
    int o=1;
    for(int u=1;u<=n;++u){
        for(int i=0;i<=m;++i) fill(f[o][i],f[o][i]+(1<<m),inf);
        copy(f[o^1][m],f[o^1][m]+(1<<m),f[o][0]);
        copy(g[o^1][m],g[o^1][m]+(1<<m),g[o][0]);
        for(int i=0;i<m;++i)for(int s=0;s<1<<m;++s){
            if(i<m-1){
                int t=s|1<<i|1<<(i+1);
                int64 v=f[o][i][s]+B[u][i]-mid;
                int c=g[o][i][s]+1;
                if(f[o][i+2][t]>v or (f[o][i+2][t]==v and g[o][i+2][t]<c))
                    f[o][i+2][t]=v,g[o][i+2][t]=c;
            }
            if(u>1 and ~s>>i&1){
                int t=s|1<<i;
                int64 v=f[o][i][s]+A[u-1][i]-mid;
                int c=g[o][i][s]+1;
                if(f[o][i+1][t]>v or (f[o][i+1][t]==v and g[o][i+1][t]<c))
                    f[o][i+1][t]=v,g[o][i+1][t]=c;
            }
            int t=s&~(1<<i);
            int64 v=f[o][i][s];
            int c=g[o][i][s];
            if(f[o][i+1][t]>v or (f[o][i+1][t]==v and g[o][i+1][t]<c))
                f[o][i+1][t]=v,g[o][i+1][t]=c;
        }
        o^=1;
    }
    int64 ans=inf;int K=0;
    for(int s=0;s<1<<m;++s)
        if(ans>f[o^1][m][s] or (ans==f[o^1][m][s] and K<g[o^1][m][s]))
            ans=f[o^1][m][s],K=g[o^1][m][s];
    return make_pair(ans,K);
}
void real_main(){
    read(n),read(m);
    int K=read<int>();
    for(int i=1;i<n;++i)for(int j=0;j<m;++j) read(A[i][j]);
    for(int i=1;i<=n;++i)for(int j=0;j<m-1;++j) read(B[i][j]);
    int64 l=0,r=1e14;
    while(l<r){
        int64 mid=(l+r)>>1;
        if(solve(mid).second>=K) r=mid;
        else l=mid+1;
    }
    printf("%lld
",solve(l).first+l*K);
}
int main(){
    for(int T=read<int>();T--;) real_main();
    return 0;
}

以上是关于HDU6094 Rikka with K-Match的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5634 Rikka with Phi

hdu 6090 Rikka with Graph

HDU 6095: Rikka with Competition

图论(生成树):HDU 5631Rikka with Graph

HDU 5631 Rikka with Graph

hdu5828 Rikka with Sequence