• hdu1533 最小费用最大流


    题意

    题意很简单,给一张100*100以内的图,H和m个数相同,进行匹配,求路径最小的一个方案

    思路

    建立两个源点,s和t。然后将H和m的位置离散化,s连接H,t连接s,H和m连接流量1,费用为两个坐标的曼哈顿距离。bellmanford一套就ok

    bellmanford模板

    struct node{
        int next,to,flow,cost,c;
    }edge[M];
    int head[N],tot,s,t;
    int maxflow,mincost;//最大流 最小费用
    void inint(){mem(head,-1);tot=0;}
    void add(int u,int v,int c,int cost){
        edge[tot].next=head[u];edge[tot].to=v;edge[tot].c=c;edge[tot].flow=0;edge[tot].cost=cost;head[u]=tot++;
        edge[tot].next=head[v];edge[tot].to=u;edge[tot].c=0;edge[tot].flow=0;edge[tot].cost=-cost;head[v]=tot++;
    }
    int dis[N],vis[N],pv[N],pe[N],a[N];
    bool bellmanford(int s,int t){
        for(int i=0;i<N;i++){dis[i]=inf;vis[i]=0;pv[i]=-1;}
        dis[s]=0;pv[s]=-1;a[s]=inf;
        queue<int>q;
        q.push(s);
        vis[s]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];~i;i=edge[i].next){
                int v=edge[i].to,cap=edge[i].c,flow=edge[i].flow,cost=edge[i].cost;
                if(cap>flow && dis[v]>dis[u]+cost){
                    dis[v]=dis[u]+cost;
                    pv[v]=u;
                    pe[v]=i;
                    a[v]=min(a[u],cap-flow);
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
        if(dis[t]==inf){
            return false;
        }
        maxflow+=a[t];
        mincost+=dis[t]*a[t];
        for(int i=t;i!=s;i=pv[i]){
            edge[pe[i]].flow+=a[t];
            edge[pe[i]^1].flow-=a[t];
        }
        return true;
    }
    void kkkk(){
        while(bellmanford(s,t)){continue;}
        return;
    }
    

    ac代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(a,b) make_pair(a,b)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 1000000007
    const double pi=acos(-1.0);
    const int N=1e4+10,M=2e5+10;
    int n,m;
    char mp[110][110];
    int H[10010],man[10010],Hnum,mannum;
    struct node{
        int next,to,flow,cost,c;
    }edge[M];
    int head[N],tot,s,t;
    int maxflow,mincost;//最大流 最小费用
    void inint(){mem(head,-1);tot=0;}
    void add(int u,int v,int c,int cost){
        edge[tot].next=head[u];edge[tot].to=v;edge[tot].c=c;edge[tot].flow=0;edge[tot].cost=cost;head[u]=tot++;
        edge[tot].next=head[v];edge[tot].to=u;edge[tot].c=0;edge[tot].flow=0;edge[tot].cost=-cost;head[v]=tot++;
    }
    int dis[N],vis[N],pv[N],pe[N],a[N];
    bool bellmanford(int s,int t){
        for(int i=0;i<N;i++){dis[i]=inf;vis[i]=0;pv[i]=-1;}
        dis[s]=0;pv[s]=-1;a[s]=inf;
        queue<int>q;
        q.push(s);
        vis[s]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];~i;i=edge[i].next){
                int v=edge[i].to,cap=edge[i].c,flow=edge[i].flow,cost=edge[i].cost;
                if(cap>flow && dis[v]>dis[u]+cost){
                    dis[v]=dis[u]+cost;
                    pv[v]=u;
                    pe[v]=i;
                    a[v]=min(a[u],cap-flow);
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
        if(dis[t]==inf){
            return false;
        }
        maxflow+=a[t];
        mincost+=dis[t]*a[t];
        for(int i=t;i!=s;i=pv[i]){
            edge[pe[i]].flow+=a[t];
            edge[pe[i]^1].flow-=a[t];
        }
        return true;
    }
    void kkkk(){
        while(bellmanford(s,t)){continue;}
        return;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            if(n==0&& m==0){return 0;}
            getchar();inint();
            for(int i=0;i<n;i++){
                scanf("%s",mp[i]);
            }
            Hnum=0;mannum=0;
            map<int,int>num;int cnt=1;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(mp[i][j]=='H'){
                        H[Hnum++]=i*100+j;
                    }
                    else if(mp[i][j]=='m'){
                        man[mannum++]=i*100+j;
                    }
                }
            }
            s=0;t=Hnum+mannum+1;maxflow=0;mincost=0;
            for(int i=0;i<Hnum;i++){
                for(int j=0;j<mannum;j++){
                    if(num[H[i]]==0){
                        num[H[i]]=cnt++;
                    }
                    if(num[man[j]]==0){
                        num[man[j]]=cnt++;
                    }
                    add(num[H[i]],num[man[j]],1,abs(H[i]/100-man[j]/100)+abs(H[i]%100-man[j]%100));
    
                }
            }
            for(int i=0;i<Hnum;i++)add(s,num[H[i]],1,0);
            for(int j=0;j<mannum;j++)add(num[man[j]],t,1,0);
            kkkk();
            //cout<<maxflow<<endl;
            printf("%d
    ",mincost);
        }
        return 0;
    }
    
  • 相关阅读:
    OpenCV -- CV_8UC1,CV_32FC3等参数的含义
    OpenCV -- 命名空间及相关函数介绍
    Qt -- QMutex使用详解
    QT -- 常用数据结构及函数
    Qt -- QQueue用法
    Qt -- QSetting类/ini配置文件的读写操作
    QT--日期操作QDateTime
    设备接口总汇(含实物图)
    “SurfFeatureDetector”: 未声明的标识符/不能实例化抽象类
    OpenCV -- Shi-Tomas角点检测与亚像素级角点检测
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/13751329.html
Copyright © 2020-2023  润新知