首页 > 代码库 > HDU 4862 Jump 最小k路径覆盖 费用流
HDU 4862 Jump 最小k路径覆盖 费用流
gg。。。
题意:
给定n*m的矩阵
选<=k个起点
每个起点可以向右或向下跳任意步
花费是2点间的曼哈顿距离
若2个格子的数字一样
则赚取格子上的数字的价值
问:遍历整个图的最小花费
若不能遍历则输出-1
#include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #include <algorithm> #include <stdlib.h> using namespace std; #define ll int #define N 220 #define M 12345 #define inf (1<<29) //注意 点标必须是 [0 - 汇点] //双向边,注意RE struct Edge{ ll from, to, flow, cap, nex, cost; }edge[M*2]; ll head[N], edgenum; void add(ll u,ll v,ll cap,ll cost){//网络流要加反向弧 Edge E={u, v, 0, cap, head[u], cost}; edge[edgenum]=E; head[u]=edgenum++; Edge E2={v, u, 0, 0, head[v], -cost}; //这里的cap若是单向边要为0 edge[edgenum]=E2; head[v]=edgenum++; } ll D[N], P[N], A[N]; bool inq[N]; bool BellmanFord(ll s, ll t, ll &flow, ll &cost){ for(ll i=0;i<=t;i++) D[i]= inf; memset(inq, 0, sizeof(inq)); D[s]=0; inq[s]=1; P[s]=0; A[s]=inf; queue<ll> Q; Q.push( s ); while( !Q.empty()){ ll u = Q.front(); Q.pop(); inq[u]=0; for(ll i=head[u]; i!=-1; i=edge[i].nex){ Edge &E = edge[i]; if(E.cap > E.flow && D[E.to] > D[u] +E.cost){ D[E.to] = D[u] + E.cost ; P[E.to] = i; A[E.to] = min(A[u], E.cap - E.flow); if(!inq[E.to]) Q.push(E.to) , inq[E.to] = 1; } } } if(D[t] == inf) return false; flow += A[t]; cost += D[t] * A[t]; ll u = t; while(u != s){ edge[P[u]].flow += A[t]; edge[P[u]^1].flow -= A[t]; u = edge[P[u]].from; } return true; } ll flow; ll Mincost(ll s,ll t){//返回最小费用 flow = 0 ; ll cost = 0; while(BellmanFord(s, t, flow, cost)); return cost; } void init(){memset(head,-1,sizeof head); edgenum = 0;} ll n, m, k; ll Hash1(ll x, ll y){ return (x-1)*m+y;} ll Hash2(ll x, ll y){ return n*m + (x-1)*m+y; } char s[20]; ll mp[20][20]; int main(){ int T, i, j, g, Cas = 1; scanf("%d",&T); while(T--){ cin>>n>>m>>k; for(i = 1; i <= n; i++) { scanf("%s",s+1); for(j = 1; j<=m; j++) mp[i][j] = s[j] - '0'; } printf("Case %d : ", Cas++); init(); ll i, j, g; ll from = 0, to = Hash2(n,m)+10, jiji = to-2; for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { add(from, Hash1(i,j), 1, 0); add(Hash2(i,j), to, 1, 0); add(jiji, Hash2(i,j), 1, 0); for(g = j+1; g <= m; g++) { ll cos = g - j - 1; if(mp[i][j] == mp[i][g]) cos -= mp[i][j]; add(Hash1(i,j), Hash2(i, g), 1, cos); } for(g = i+1; g <= n; g++) { ll cos = g - i - 1; if(mp[i][j] == mp[g][j]) cos -= mp[i][j]; add(Hash1(i,j), Hash2(g, j), 1, cos); } } } add(from, jiji, k, 0); ll ans = - Mincost(from, to); if(flow != n*m) puts("-1"); else cout<< ans << endl; } return 0; } /* 99 2 5 1 11111 11111 2 5 2 11111 11111 2 5 2 01110 10101 2 5 3 10101 02110 1 5 100 91929 10 10 100 4545654101 1531321564 5125641234 1564531045 2313543132 5644134541 1313413243 5478964165 1234468612 1213541550 */
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。