HDOJ 4862 Jump(最小费用最大流)

来源:互联网 发布:淘宝网店装修教程视频 编辑:程序博客网 时间:2024/06/08 02:10
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <vector>#include <cmath>#define LL long longusing namespace std;const int maxn = 1000 + 10;const int INF = 10000000;struct Edge{    int from,to,cap,flow,cost;    Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w) { }};int n;vector<Edge>edges;vector<int>G[maxn];int inq[maxn];int d[maxn];int p[maxn];int a[maxn];void init(){    for(int i=0;i<=n;i++)        G[i].clear();    edges.clear();}void addedge(int from,int to,int cap,int cost){    edges.push_back(Edge(from,to,cap,0,cost));    edges.push_back(Edge(to,from,0,0,-cost));    int M = edges.size();    G[from].push_back(M-2);    G[to].push_back(M-1);}bool SPFA(int s,int t,int& flow,int& cost){    for(int i=0;i<=n+1;i++)        d[i] = INF;    memset(inq,0,sizeof(inq));    d[s] = 0;inq[s] = 1;p[s] = 0;a[s] = INF;    queue<int>Q;    Q.push(s);    while(!Q.empty())    {        int u = Q.front();Q.pop();        inq[u] = 0;        for(int i=0;i<G[u].size();i++)        {            Edge& e = edges[G[u][i]];            if(e.cap > e.flow && d[e.to] > d[u] + e.cost)            {                d[e.to] = d[u] + e.cost;                p[e.to] = G[u][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 += (LL)d[t] * (LL)a[t];    for(int u=t;u!=s;u=edges[p[u]].from)    {        edges[p[u]].flow += a[t];        edges[p[u]^1].flow -= a[t];    }    return true;}int MincostMaxflow(int s,int t,int &cost){    int flow = 0;cost = 0;    while(SPFA(s,t,flow,cost));    return flow;}int N,M,K;char str[12][12];void solve(){n = 2 * N * M + 3;    init();    int start = 2*N*M;    int end = 2*N*M+2;    addedge(start,start+1,K,0);    for(int i = 0;i < N;i++)        for(int j = 0;j < M;j++)        {            addedge(start,2*(i*M+j),1,0);            addedge(2*(i*M+j)+1,end,1,0);            addedge(start+1,2*(i*M+j)+1,1,0);            for(int y = j+1;y < M;y++)            {                if(str[i][y] == str[i][j])                    addedge(2*(i*M+j),2*(i*M+y)+1,1,-(str[i][j]-'0')+y-j-1);                else addedge(2*(i*M+j),2*(i*M+y)+1,1,y-j-1);            }            for(int x = i+1; x < N;x++)            {                if(str[x][j] == str[i][j])                    addedge(2*(i*M+j),2*(x*M+j)+1,1,-(str[i][j]-'0')+x-i-1);                else addedge(2*(i*M+j),2*(x*M+j)+1,1,x-i-1);            }        }    int cost = 0;    int flow = MincostMaxflow(start,end,cost);    if(flow != N*M)printf("-1\n");    else printf("%d\n",-cost);}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    scanf("%d",&T);    int iCase = 0;    while(T--)    {        iCase++;        scanf("%d%d%d",&N,&M,&K);        for(int i = 0;i < N;i++)            scanf("%s",str[i]);        printf("Case %d : ",iCase);        solve();    }    return 0;}

0 0