zoukankan      html  css  js  c++  java
  • poj 3422 Kaka's Matrix Travels (费用流 + 拆点)


     这道题以前做过了 今天有做了一遍,发现比以前顺手多了,

    题意:

    给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数(每一个 方格只能向下 后向右走), 然后这个格上面的数变为0。求可取得的最大的值。
     

    题解:

     拆点 + 费用流 ;

    将 每一个点拆分成两个 , 为了  保证 只能算一次  流量为1  花费为  方格的值,有为了 保证 其他的路径 可以 从这个点 走过  再建一条  流量 为  inf  费用 为 0 的 边 

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<string>
     11 #define Min(a,b) a<b?a:b
     12 #define Max(a,b) a>b?a:b
     13 #define CL(a,num) memset(a,num,sizeof(a));
     14 #define eps  1e-12
     15 #define inf 10001000
     16 #define mx 1<<60
     17 #define ll   __int64
     18 
     19 #define  read()  freopen("data.txt","r",stdin) ;
     20 const double pi  = acos(-1.0);
     21 const int maxn = 100000;
     22 
     23 using namespace std;
     24 int n , m , k ,s,ss,t,N;
     25 int mat[60][60] ,dis[6000],head[6000],cnt,pre[6000];
     26 bool vis[6000] ;
     27 struct node
     28 {
     29     int v;
     30     int cost;
     31     int flow;
     32     int next ;
     33 }p[maxn] ;
     34 struct qnode
     35 {
     36     int u;
     37     int  len ;
     38     qnode(int a,int b):u(a),len(b){}
     39 
     40 };
     41 queue<qnode>que ;
     42 
     43 
     44 void add(int u,int v,int f,int c)
     45 {
     46     p[cnt].v = v;
     47     p[cnt].cost = c ;
     48     p[cnt].flow = f;
     49     p[cnt].next = head[u];
     50     head[u] = cnt++;
     51 
     52 
     53 
     54     p[cnt].v = u;
     55     p[cnt].cost = -c;
     56     p[cnt].flow = 0;
     57     p[cnt].next = head[v] ;
     58     head[v] = cnt++ ;
     59 
     60 }
     61 void build()
     62 {
     63     int  i , j ,b;
     64     CL(head,-1);
     65 
     66     cnt = 0 ;
     67     N = n*n ;
     68     s = n*n *21 ;
     69     t = n*n *2 + 2 ;
     70     add(s,0,k,0);
     71 
     72     for(i = 0 ; i < n;i++)
     73     {
     74         for(j = 0 ; j< n;j++)
     75         {
     76              int a = i*n + j;
     77 
     78              add(a,a + N,1,mat[i][j]) ;
     79              add(a,a+N,inf,0) ;
     80              if(i + 1 < n)
     81              {
     82                  b = (i + 1)*n + j ;
     83                  add(a + N,b,inf,0) ;
     84              }
     85 
     86              if(j + 1 < n)
     87              {
     88                  b =  i * n + (j  + 1) ;
     89                  add(a + N,b,inf,0) ;
     90              }
     91 
     92              if(i == n - 1&&j == n - 1)
     93              {
     94                  add(a + N,t,inf,0);
     95              }
     96         }
     97     }
     98 
     99 
    100 
    101 }
    102 bool spfa(int s)
    103 {
    104 
    105     int i ;
    106     for(i = 0 ; i <= t;i++)
    107     {
    108         dis[i] = -inf;
    109     }
    110     dis[s] = 0 ;
    111     CL(vis,false) ;
    112     while(!que.empty())que.pop() ;
    113 
    114     que.push(qnode(s,0));
    115     vis[s] =true ;
    116     while(!que.empty())
    117     {
    118         qnode a = que.front() ;que.pop() ;
    119 
    120         int u = a.u;
    121         int len = a.len ;
    122         vis[u] = false ;
    123         for(i = head[u];i != - 1;i = p[i].next)
    124         {
    125             int v = p[i].v;
    126             int cost = p[i].cost;
    127             int flow = p[i].flow ;
    128             if(flow > 0 && dis[v] <  dis[u] + cost)
    129             {
    130 
    131                 dis[v] = dis[u] + cost;
    132                 pre[v] = i;
    133                 if(!vis[v])
    134                 {
    135                     vis[v] = true ;
    136                     que.push(qnode(v,dis[v])) ;
    137                 }
    138             }
    139         }
    140     }
    141     return dis[t] > 0 ;
    142 
    143 }
    144 void solve()
    145 {
    146     int  i, j;
    147     int res = -inf ;
    148 
    149 
    150 
    151         int ans = 0 ;
    152 
    153         while(spfa(s))
    154         {
    155 
    156 
    157             int mi =  inf;
    158             int tp = t;
    159             /*while(tp!= s)
    160             {
    161 
    162 
    163                 mi = min(mi,p[pre[tp]].flow) ;
    164                 tp = p[pre[tp]^1].v ;// 跳到 出边点
    165             }
    166             tp = t;*/
    167             while(tp!= s)
    168             {
    169 
    170                 ans += p[pre[tp]].cost ;
    171                 p[pre[tp]].flow -= 1 ;
    172                 p[pre[tp]^1].flow += 1;
    173 
    174                 tp = p[pre[tp]^1].v;
    175 
    176             }
    177         }
    178 
    179 
    180 
    181      printf("%d\n",ans) ;
    182 
    183 }
    184 int main()
    185 {
    186     int i ,u,v,d,j;
    187     //read();
    188     while(scanf("%d%d",&n,&k)!=EOF)
    189     {
    190         for(i = 0 ; i< n;i++)
    191         {
    192             for(j = 0 ; j < n;j++)
    193             {
    194                 scanf("%d",&mat[i][j]) ;
    195             }
    196         }
    197         build() ;
    198         solve() ;
    199     }
    200 }
  • 相关阅读:
    PCA理论与实践
    深度挖掘客户价值—分析角度篇
    多元线性回归理论与实践
    数据分析框架
    Growing转化的每一步(笔记整理)
    kmeans算法原理以及实践操作(多种k值确定以及如何选取初始点方法)
    mysql查询优化(持续更新中)
    mysql 各种运算对于null值的处理
    left join与on,where 结合一起用的异同
    Spark(十一) -- Mllib API编程 线性回归、KMeans、协同过滤演示
  • 原文地址:https://www.cnblogs.com/acSzz/p/2706292.html
Copyright © 2011-2022 走看看