zoukankan      html  css  js  c++  java
  • poj3422 Kaka's Matrix Travels

    传送门

    这个题一开始感觉像两条路径和 毕竟求的东西名字都一样

    后来发现不行 因为那个是强制限制一条边只能走一次

    这个是以后还可以走但是没有价值了

    所以考虑一下拆点

    不同的地方在于每个点只能走一次有权值的路径

    所以拆的点之间建两条边 一条有权值流量为1 一条没权值流量为k-1

    然后起点连源 终点连汇 左上右部图连右下左部图都是套路

    注意求最大费用 取相反数即可

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #define ms(a,b) memset(a,b,sizeof a)
     7 #define rep(i,a,n) for(int i = a;i <= n;i++)
     8 #define per(i,n,a) for(int i = n;i >= a;i--)
     9 #define inf 2147483647
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double D;
    13 #define eps 1e-8
    14 ll read() {
    15     ll as = 0,fu = 1;
    16     char c = getchar();
    17     while(c < '0' || c > '9') {
    18         if(c == '-') fu = -1;
    19         c = getchar();
    20     }
    21     while(c >= '0' && c <= '9') {
    22         as = as * 10 + c - '0';
    23         c = getchar();
    24     }
    25     return as * fu;
    26 }
    27 //head
    28 const int N = 10005;
    29 const int M = 100005;
    30 int s = N-1,t = N-2;
    31 int head[N],nxt[M],mo[M],cnt = 1;
    32 int cst[M],flw[M];
    33 void _add(int x,int y,int w,int f) {
    34     mo[++cnt] = y;
    35     nxt[cnt] = head[x];
    36     head[x] = cnt;
    37     cst[cnt] = w,flw[cnt] = f;
    38 }
    39 void add(int x,int y,int f,int w) {
    40     if(x^y)_add(x,y,w,f),_add(y,x,-w,0);
    41 }
    42 
    43 int dis[N],flow[N];
    44 int pre[N],lst[N];
    45 bool vis[N];
    46 bool spfa() {
    47     ms(dis,70),ms(flow,70),ms(vis,0);
    48     queue<int> q;
    49     q.push(s),pre[t] = dis[s] = 0,vis[s] = 1;
    50     while(!q.empty()) {
    51         int x = q.front();
    52         q.pop(),vis[x] = 0;
    53         for(int i = head[x];i;i = nxt[i]) {
    54             int sn = mo[i];
    55             if(dis[sn] > dis[x] + cst[i] && flw[i]) {
    56                 dis[sn] = dis[x] + cst[i];
    57                 pre[sn] = x,lst[sn] = i;
    58                 flow[sn] = min(flow[x],flw[i]);
    59                 if(!vis[sn]) vis[sn] = 1,q.push(sn);
    60             }
    61         }
    62     }
    63     return pre[t];
    64 }
    65 
    66 int maxx,minn;
    67 void MCMF() {
    68     maxx = minn = 0;
    69     while(spfa()) {
    70         maxx += flow[t],minn += dis[t] * flow[t];
    71         int x = t;
    72         while(x ^ s) {
    73             flw[lst[x]] -= flow[t];
    74             flw[lst[x] ^ 1] += flow[t];
    75             x = pre[x];
    76         }
    77     }
    78 }
    79 
    80 int n,k;
    81 int idx(int x,int y,int f) {return (x-1) * n + y + f * n * n;}
    82 
    83 void build() {
    84     n = read(),k = read();
    85     rep(i,1,n) rep(j,1,n) add(idx(i,j,0),idx(i,j,1),1,-read());
    86     rep(i,1,n) rep(j,1,n) add(idx(i,j,0),idx(i,j,1),k-1,0);
    87     add(s,idx(1,1,0),k,0);
    88     add(idx(n,n,1),t,k,0);
    89     rep(i,1,n) rep(j,1,n) {
    90         if(i < n) add(idx(i,j,1),idx(i+1,j,0),k,0);
    91         if(j < n) add(idx(i,j,1),idx(i,j+1,0),k,0);
    92     }
    93 }
    94 
    95 int main() {
    96     build(),MCMF(),printf("%d
    ",-minn);
    97     return 0;
    98 }
  • 相关阅读:
    BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)
    BZOJ 4522: [Cqoi2016]密钥破解 (Pollard-Rho板题)
    BZOJ 4802: 欧拉函数 (Pollard-Rho)
    BZOJ 3944: Sum (杜教筛)
    BZOJ 3309: DZY Loves Math (莫比乌斯反演)
    BZOJ 2599: [IOI2011]Race(点分治板题)
    BZOJ 3680: 吊打XXX // Luogu [JSOI2004]平衡点 / 吊打XXX (模拟退火)
    Luogu P3690【模板】Link Cut Tree (LCT板题)
    [HNOI2007]最小矩形覆盖
    [SCOI2007]最大土地面积
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10028844.html
Copyright © 2011-2022 走看看