Going Home HDU - 1533

这里写图片描述
这里写图片描述
1.建立源点 S与所有的人连 ,流量为1,费用为0。
2.建立汇点 T与所有的房子连,流量为1,费用为0。
之后遍历每个人,然后加边,每个人与每个房子连,流量为1,费用为两个点为曼哈顿距离。

https://blog.csdn.net/qq_37383726/article/details/78177558

#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define  LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)

const int maxn = 10000+10;
const int maxm = 100+10;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

struct Edge
{
    int from,to,next,cap,flow,cost;
}edge[maxn*10];

int head[maxn],top;

void init()
{
    memset(head,-1,sizeof(head));
    top = 0;
}

void addege(int a,int b,int w,int c)
{
    edge[top].from = a,edge[top].to = b,edge[top].cap = w,edge[top].flow = 0,edge[top].cost = c,edge[top].next=head[a];
    head[a] = top++;
    edge[top].from = b,edge[top].to = a,edge[top].cap = 0,edge[top].flow = 0,edge[top].cost = -c,edge[top].next = head[b];
    head[b] = top++;
}

int n,m;
typedef pair<int,int> P;
vector<P> man;
vector<P> home;
int S,T;

void getmap()
{
    char ss[maxn];
    man.clear();home.clear();
    int a,b;
    a = b = 0;
    for(int i = 1 ; i <= n ; i++)
    {
        scanf("%s",ss);
        for(int j = 0 ; ss[j]; j++)
        {
            if(ss[j] == 'H')
            {
                home.push_back({i,j+1});
                a++;
            }
            else if(ss[j] == 'm')
            {
                man.push_back({i,j+1});
                b++;
            }
        }
    }
    S = 0;T = a+b+1;
    for(int i = 0 ; i < man.size() ;i++)
    addege(S,i+1,1,0);
    for(int j = 0 ; j < home.size() ; j++)
    addege(a+j+1,T,1,0);
    for(int i = 0 ; i < man.size() ; i++)
    {
        for(int j = 0 ; j < home.size() ; j++)
        addege(i+1,a+j+1,1,abs(man[i].first-home[j].first)+abs(man[i].second-home[j].second));
    }
}

bool vis[maxn];int dis[maxm];
int pre[maxn];
bool spfa(int s,int e)
{
    queue<int> Q;
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    memset(pre,-1,sizeof(pre));
    dis[s] = 0;vis[s] = 1;Q.push(s);
    while(!Q.empty())
    {
        int now = Q.front();
        Q.pop();
        vis[now] = 0;
        for(int i = head[now];i!=-1;i = edge[i].next)
        {
            Edge e = edge[i];
            if(e.cap>e.flow&&dis[e.to]>dis[now]+e.cost)
            {
                dis[e.to] = dis[now]+e.cost;
                pre[e.to] = i;
                if(!vis[e.to])
                {
                    vis[e.to] = 1;
                    Q.push(e.to);
                }
            }
        }
    }
    return pre[e]!=-1;
}

int MCMF(int s,int t,int &cost,int &flow)
{
    flow = cost = 0;
    while(spfa(s,t))
    {
        int Min = inf;
        for(int i = pre[t];i!=-1;i = pre[edge[i^1].to])
        {
            Min = min(Min,edge[i].cap-edge[i].flow);
        }
        for(int i = pre[t];i!=-1;i = pre[edge[i^1].to])
        {
            edge[i].flow+=Min;
            edge[i^1].flow -= Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
}

int main()
{
    while(scanf("%d%d",&n,&m)&&(n||m))
    {
        init();
        getmap();
        int flow,ans;
        MCMF(S,T,ans,flow);
        printf("%d\n",ans);
    }
    return 0;
}











猜你喜欢

转载自blog.csdn.net/qq_40240576/article/details/82390291
今日推荐