最小费用最大流 HDU1533

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1533

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e6+8;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=1e9+7;
const ULL base=1e7+7;
using namespace std;
struct edge{
    int to,nxt,flow,cost;
}g[maxn];
int head[10008],pre[10008],dis[10008],cnt,s,t,tot;
int a[108][108];
bool vis[10008];
char ss[108];
void add(int x,int y,int cost,int flow){
    g[cnt].to=y;
    g[cnt].nxt=head[x];
    g[cnt].cost=cost;
    g[cnt].flow=flow;
    head[x]=cnt++;
}
bool spfa(){
    memset(pre,-1,sizeof(pre));
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<int> que;
    while(!que.empty()){que.pop();}
    que.push(s);
    dis[s]=0;
    vis[s]=1;
    while(!que.empty()){
        int k=que.front();
        que.pop();
        vis[k]=0;
        int tt=head[k];
        while(tt!=-1){
            if(dis[g[tt].to]>dis[k]+g[tt].cost&&g[tt].flow>0){
                pre[g[tt].to]=tt;
                dis[g[tt].to]=dis[k]+g[tt].cost;
                if(vis[g[tt].to]==0){
                    que.push(g[tt].to);
                    vis[g[tt].to]=1;
                }
            }
            tt=g[tt].nxt;
        }
    }
    return pre[t]!=-1;
}
int maxflow(){
    int ans=0;
    while(spfa()){
        int f=INF;
        for(int i=pre[t];i!=-1;i=pre[g[i^1].to]){
            if(g[i].flow<f)
                f=g[i].flow;
        }
        for(int i=pre[t];i!=-1;i=pre[g[i^1].to]){
            g[i].flow-=f;
            g[i^1].flow+=f;
            ans+=g[i].cost*f;
        }
    }
    return ans;
}
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF&&n&&m){
        memset(head,-1,sizeof(head));
        cnt=tot=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=tot++;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(j!=m){
                    add(a[i][j],a[i][j+1],1,INF);
                    add(a[i][j+1],a[i][j],-1,0);
                    add(a[i][j+1],a[i][j],1,INF);
                    add(a[i][j],a[i][j+1],-1,0);
                }
                if(i!=n){
                    add(a[i][j],a[i+1][j],1,INF);
                    add(a[i+1][j],a[i][j],-1,0);
                    add(a[i+1][j],a[i][j],1,INF);
                    add(a[i][j],a[i+1][j],-1,0);
                }
            }
        }
        s=tot++;
        t=tot++;
        for(int i=1;i<=n;i++){
            scanf("%s",ss);
            for(int j=0;j<m;j++){
                if(ss[j]=='H'){
                    add(a[i][j+1],t,0,1);
                    add(t,a[i][j+1],0,0);
                }
                if(ss[j]=='m'){
                    add(s,a[i][j+1],0,1);
                    add(a[i][j+1],s,0,0);
                }
            }
        }
        printf("%d\n",maxflow());
    }
}

 

posted @ 2018-10-19 17:39  我要见血小板  阅读(176)  评论(0编辑  收藏  举报