P1559 athletes the best matching problem [maximum cost maximum flow]

Title Description

There are various sportsmen and women badminton team n people. Given two n × n matrix P and Q. P [i] [j] is competition advantages male athletes and female athletes Male athletes i j mixed doubles pair consisting of; Q [i] [j] is male athletes and female athletes i j with the advantages of competition female athletes. And due to the psychological state of technology with other factors, P [i] [j] is not necessarily equal to Q [j] [i]. Male athletes and female athletes j i mixed doubles pair consisting of the strengths of both men and women race as P [i] [j] * Q [j] [i]. Design an algorithm to calculate the best male and female athletes paired law so that both men and women in each group reach the maximum sum competition advantage.

Resolve

This question is n is small, explosive search to get out is not a problem, but I do not like the burst search,Often wrong

Obviously we want is a maximum weighted bipartite graph matching, the maximum cost of seeking the maximum flow, spfa longest road + EK maximum flow.

Of course, this question is obviously a perfect match, KM algorithm can,But I did not learn


Attention to detail, when the construction cost side, the reverse side is set to the right side of the forward side opposite number.

Sensibility to understand it, we must first understand augmenting path algorithm can go back on the path, meaning that one way to search is not legitimate when it comes back and the answer will not be affected along the reverse side, so we will use the time to go back in opposite number to offset the cost of lost influence.

Reference Code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 51
#define M 10010
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct rec{
    int next,ver,leng,edge;
}g[M<<1];
int head[M],tot=1,d[M],n,p[N][N],q[N][N],now[N],pre[N];
int ans;
bool v[M];
inline void add(int x,int y,int val,int e)
{
    g[++tot].ver=y,g[tot].leng=val,g[tot].edge=e;
    g[tot].next=head[x],head[x]=tot;
}
inline bool spfa()
{
    fill(d,d+N,-INF);
    memset(v,0,sizeof(v));
    queue<int> q;
    v[0]=1;d[0]=0;now[0]=INF;q.push(0);
    while(q.size()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x];i;i=g[i].next){
            int y=g[i].ver,z=g[i].edge,leng=g[i].leng;
            if(!leng||d[y]>=d[x]+z) continue;
            d[y]=d[x]+z;
            now[y]=min(now[x],leng);
            pre[y]=i;
            if(!v[y]) v[y]=1,q.push(y);
        }
    }
    if(d[2*n+1]==-INF) return 0;
    else return 1;
}
inline void change()
{
    ans+=d[2*n+1]*now[2*n+1];
    int tmp=2*n+1;
    while(tmp!=0){
        int i=pre[tmp];
        g[i].leng-=now[2*n+1];
        g[i^1].leng+=now[2*n+1];
        tmp=g[i^1].ver;
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i) add(0,i,1,0),add(i,0,0,0),add(i+n,n*2+1,1,0),add(n*2+1,i+n,0,0);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            p[i][j]=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            q[i][j]=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            add(i,j+n,1,p[i][j]*q[j][i]),add(j+n,i,0,-p[i][j]*q[j][i]);
    while(spfa()) change();
    cout<<ans<<endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11426111.html