zoukankan      html  css  js  c++  java
  • HDU 4862 Jump(最小K路径覆盖)

    输入一个n×m网格图,每个结点的值为0~9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值。不可全部走完的情况输出-1.

    初始能量为0。 而结点(x,y)可以跳跃到结点(x,y+dy)或(x+dx,y)。消耗能量为跳跃前后结点的曼哈顿距离 - 1 。若跳跃前后的结点的值相等,能量加上那个值。

    具体建图可以参考这里http://blog.sina.com.cn/s/blog_6bddecdc0102uy9g.html

    最小K路径覆盖其实在之前是见过的打过的,不过这次又不会了,说明之前不牢固。。。要认真点,没什么时间浪费了。

    平时在求二分图的无权的最小覆盖的时候,用的就是 n - 最大匹配

    那个从源点连流量为K,费用为0的边到的“那个结点”,实际上就上虚拟前驱。。。因为X集合其实就是Y集合的前驱。而起点的前驱就是没有前驱,即“那个结点”。

    然后如果满流量的话,说明所有结点都走了一遍。

    模板是找JM伙伴要的。。。据说伙伴是参考KH师兄的=。=

    其实最近经常问JM题。。。感觉自己退步了=。=要加油!!!

      1 #include<cstdio>
      2 #include<set>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<algorithm>
      8 #include<queue>
      9 #include<cmath>
     10 using namespace std;
     11 
     12 
     13 #define maxn 222
     14 #define maxe 30000
     15 #define inf 0x3f3f3f3f
     16 
     17 struct Edge{
     18     int u, v, nxt, cap, cost;
     19 }edge[maxe];
     20 int head[maxn];
     21 
     22 struct MinCostMaxFlow{
     23     queue<int> que;
     24     int add; // edges number
     25     int vn; // total vertex number
     26     int cost[maxn], in[maxn], pre[maxn];
     27     bool vis[maxn];
     28     void init(int sz){
     29         add = 0; vn = sz + 10; memset(head, -1, sizeof(head));
     30         while (!que.empty()) que.pop();
     31     }
     32     void insert(int u, int v, int w, int c){// u, v, capacity, cost
     33         edge[add].u = u; edge[add].v = v; edge[add].cap = w; edge[add].cost = c;
     34         edge[add].nxt = head[u]; head[u] = add++;
     35         edge[add].u = v; edge[add].v = u; edge[add].cap = 0; edge[add].cost = -c;
     36         edge[add].nxt = head[v]; head[v] = add++;
     37     }
     38     bool spfa(int s, int e){
     39         memset(cost, 0x3f3f3f3f, sizeof(cost));
     40         memset(in, 0, sizeof(in));
     41         memset(vis, 0, sizeof(vis));
     42         cost[s] = 0; pre[s] = -1;
     43         que.push(s); vis[s] = true; in[s]++;
     44         while (!que.empty()){
     45             int u = que.front(); que.pop();
     46             vis[u] = false;
     47             for (int i = head[u]; i != -1; i = edge[i].nxt){
     48                 int v = edge[i].v;
     49                 if (edge[i].cap > 0 && cost[v] > cost[u] + edge[i].cost){
     50                     cost[v] = cost[u] + edge[i].cost; pre[v] = i;
     51                     if (!vis[v]){
     52                         que.push(v); vis[v] = true; in[v]++;
     53                         if (in[v] > vn) return false;
     54                     }
     55                 }
     56             }
     57         }
     58         return cost[e] < inf;
     59     }
     60     void mincostmaxflow(int s, int e, int &mincost, int &maxflow){
     61         mincost = 0, maxflow = 0;
     62         while (spfa(s, e)){
     63             int flow = inf;
     64             for (int i = pre[e]; i != -1; i = pre[edge[i].u]){
     65                 flow = min(flow, edge[i].cap);
     66             }
     67             maxflow += flow;
     68             for (int i = pre[e]; i != -1; i = pre[edge[i].u]){
     69                 edge[i].cap -= flow;
     70                 edge[i ^ 1].cap += flow;
     71             }
     72             mincost += cost[e] * flow;
     73         }
     74     }
     75 }net;
     76 
     77 int nm;
     78 char ch[22][22];
     79 int main(){
     80     int t,n,m,k,ca=0;
     81     scanf("%d",&t);
     82     while(t--){
     83         scanf("%d%d%d",&n,&m,&k);
     84         nm = n*m;
     85         for(int i=0;i<n;++i)scanf("%s",ch[i]);
     86         net.init(nm*2+3);
     87         for(int i=0;i<n;++i){
     88             for(int j=0;j<m;++j){
     89                 int u = i*m+j+1;
     90                 for(int k=i+1;k<n;++k){
     91                     int v = k*m+j+1;
     92                     int tmp = -(k-i-1);
     93                     if(ch[i][j]==ch[k][j]) tmp+=ch[i][j]-'0';
     94                     net.insert(u,nm+v,1,-tmp);
     95                 }
     96                 for(int k=j+1;k<m;++k){
     97                     int v = i*m+k+1;
     98                     int tmp = -(k-j-1);
     99                     if(ch[i][j]==ch[i][k]) tmp+=ch[i][j]-'0';
    100                     net.insert(u,nm+v,1,-tmp);
    101                 }
    102             }
    103         }
    104         for(int i=nm+1;i<=nm*2;++i) net.insert(nm*2+1,i,1,0);
    105         for(int i=1;i<=nm;++i) net.insert(0,i,1,0);
    106         net.insert(0,nm*2+1,k,0);
    107         for(int i=nm+1;i<=nm*2;++i)net.insert(i,nm*2+2,1,0);
    108         int cost,flow;
    109         net.mincostmaxflow(0,nm*2+2,cost,flow);
    110         printf("Case %d : ",++ca);
    111         if(flow==nm) printf("%d
    ",-cost);
    112         else puts("-1");
    113     }
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    ideaIU-2017.1.1.exe安装、注册、汉化IntelliJ IDEA
    504 Gateway Timeout 异常
    Windows下80端口被进程System占用的解决方法
    D2Admin基本使用
    MySQL 教程
    Element 插件
    VSCode-Element-Helper
    ECharts 教程
    JSP 教程
    Kotlin 教程 Android 官方开发语言
  • 原文地址:https://www.cnblogs.com/nextbin/p/3863911.html
Copyright © 2011-2022 走看看