zoukankan      html  css  js  c++  java
  • HOJ

    国庆八天乐,刷题也快乐。

    HOJ崩了,但是VJ可以把题目挂出来。

    题目链接:https://vjudge.net/contest/188441#problem/A

    涉及到矩阵里面的网络流,化为图来做。

    某个点有流量限制,一定要想到拆点。

    求最大值的话,要把w变成负数。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 #include <algorithm>
      7 using namespace std;
      8 const int maxn = 6e3;
      9 const int INF = 1e9;
     10 int vis[maxn],dist[maxn];
     11 int tot,head[maxn];
     12 int pv[maxn],pe[maxn];
     13 struct edge
     14 {
     15     int to,pre,cap,cost;
     16 }e[100000];
     17 void init()
     18 {
     19     tot = 0;
     20     memset(head,-1,sizeof(head));
     21 }
     22 void add(int from,int to,int cap,int cost)
     23 {
     24     e[tot].pre = head[from];
     25     e[tot].to = to;
     26     e[tot].cap = cap;
     27     e[tot].cost = cost;
     28     head[from] = tot++;
     29 }
     30 void addedge(int from,int to,int cap,int cost)
     31 {
     32     add(from,to,cap,cost);
     33     add(to,from,0,-cost);
     34 }
     35 int n,k;
     36 int min_cost_flow(int s,int t,int f,int& max_flow)
     37 {
     38     int ret = 0;
     39     while(f>0&&(k--))
     40     {
     41         memset(vis,0,sizeof(vis));
     42         for(int i=0;i<maxn;i++) dist[i] = INF;
     43         dist[s] = 0;
     44         queue<int> q;
     45         q.push(s);
     46         while(!q.empty())
     47         {
     48             int v = q.front(); q.pop();
     49             vis[v] = 0;
     50             for(int i=head[v];i>=0;i=e[i].pre)
     51             {
     52                 int to = e[i].to,cap = e[i].cap,cost = e[i].cost;
     53                 if(cap>0&&dist[to]>dist[v]+cost)
     54                 {
     55                     pv[to] = v,pe[to] = i;
     56                     dist[to] = dist[v] + cost;
     57                     if(!vis[to]) q.push(to);
     58                     vis[to] = 1;
     59                 }
     60             }
     61            // printf("%d
    ",v);
     62         }
     63         //printf("%d
    ",dist[t]);
     64         if(dist[t]==INF) return ret;///同一目的地,每次增广路都是最小费用
     65         ///当所有边的流量都流净后,即没有残余网络,返回。
     66         int d = f;
     67         for(int v=t;v!=s;v=pv[v])
     68         {
     69             d = min(d,e[pe[v]].cap);
     70         }
     71         f -= d;
     72         max_flow += d;
     73         ret += d*dist[t]; ///走一单位就消耗dist[t]
     74         for(int v=t;v!=s;v=pv[v])
     75         {
     76             e[pe[v]].cap -= d;
     77             e[pe[v]^1].cap += d;
     78         }
     79     }
     80     return ret;
     81 }
     82 int height[55][55];
     83 int value[55][55];
     84 int judge(int x,int y)
     85 {
     86     if(x<=0||x>=(n-1)||y<=0||y>=(n-1)) return 1;
     87     else return 0;
     88 }
     89 int judge1(int x,int y)
     90 {
     91     if(x>=0&&x<=(n-1)&&y>=0&&y<=(n-1)) return 1;
     92     else return 0;
     93 }
     94 int to[4][2] = {1,0,-1,0,0,1,0,-1};
     95 int main()
     96 {
     97     int T;scanf("%d",&T);
     98     while(T--)
     99     {
    100         scanf("%d %d",&n,&k);
    101         init();  ///千万别忘记写
    102         for(int i=0;i<n;i++)
    103         {
    104             for(int j=0;j<n;j++)
    105             {
    106                 scanf("%d",&value[i][j]);
    107             }
    108         }
    109         for(int i=0;i<n;i++)
    110         {
    111             for(int j=0;j<n;j++)
    112             {
    113                 scanf("%d",&height[i][j]);
    114             }
    115         }
    116         int s = 2*n*n+1;
    117         int t = 2*n*n+2;
    118         for(int i=0;i<n;i++)
    119         {
    120             for(int j=0;j<n;j++)
    121             {
    122                 addedge(s,i*n+j,INF,0);
    123                 addedge(i*n+j,i*n+j+n*n,1,-value[i][j]);
    124                 addedge(i*n+j,i*n+j+n*n,INF,0);  ///addedge(i',i'',inf,0)的边,可以再次走,只不过没有宝藏了
    125                 if(judge(i,j))
    126                 {
    127                     addedge(i*n+j+n*n,t,INF,0);
    128                 }
    129             }
    130         }
    131         for(int i=0;i<n;i++)
    132         {
    133             for(int j=0;j<n;j++)
    134             {
    135                 for(int k=0;k<4;k++)
    136                 {
    137                     int nextx = i+to[k][0];
    138                     int nexty = j+to[k][1];
    139                     if(judge1(nextx,nexty)&&height[i][j]>height[nextx][nexty])
    140                     {
    141                         addedge(i*n+j+n*n,nextx*n+nexty,INF,0);
    142                     }
    143                 }
    144             }
    145         }
    146         int max_flow = 0;
    147         int ans = min_cost_flow(s,t,INF,max_flow);
    148         if(ans==0)
    149         {
    150             printf("%d
    ",ans);
    151         }
    152         else
    153         {
    154             printf("%d
    ",-ans);
    155         }
    156     }
    157     return 0;
    158 }
    159 /*
    160 4 5
    161 1 2 1
    162 2 3 1
    163 3 4 1
    164 1 3 2
    165 2 4 1
    166 */
  • 相关阅读:
    hihoCoder week20 线段树的区间修改
    hihoCoder week19 RMQ问题再临-线段树 单点更新 区间查询
    hihoCoder week17 最近公共祖先·三 lca st表
    hihoCoder week16 RMQ-ST算法
    hihoCoder week15 最近公共祖先·二
    eclipse 分屏显示同一文件
    eclipse 每次以debug方式启动springboot之后都会在SilentExitExceptionHandler类中的throw new SilentExitException()处断开,但是我明明没有下断点啊
    eclipse alt+/智能提示错误问题
    SpringBoot 之 普通类获取Spring容器中的bean
    kafka常用命令
  • 原文地址:https://www.cnblogs.com/littlepear/p/7616890.html
Copyright © 2011-2022 走看看