GYM - 101490 J Programming Tutors (匈牙利+二分)

题意:有N个学生和N个老师,每个人都有自己的坐标X,Y,给每个学生匹配一个老师,要求N个匹配中的距离最大值最小。其中距离的定义为:|X − X’| + |Y − Y ‘|.

分析:一道典型的最大值最小化的题目,可以二分逼近的方法找到最小值。二分中的check操作就用匈牙利匹配来判断。在匹配的过程中加入对边长的判断,或者直接根据边长限制建立新图。最后得到的上界就是答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e2+5;
struct Node{
    LL x,y;
}s[maxn],t[maxn];
int N;
struct Edge{
    LL val;
    int to,next;
}edges[maxn<<2];
int head[maxn],tot;
int linker[maxn];
bool used[maxn];

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

void AddEdge(int u,int v, LL val)
{
    edges[tot].val = val;
    edges[tot].to = v;
    edges[tot].next = head[u];
    head[u] = tot++;
}

bool dfs(int u,LL limit){
    int v,st,ed;
    for(int i=head[u];~i;i = edges[i].next){
        v = edges[i].to;
        if(!used[v] && edges[i].val <=limit){
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v],limit)){
                linker[v]=u;
                return true;
            }
        }
    }
    return false;
}

bool hungary(LL limit){
    int u;
    int res=0;
    memset(linker,-1,sizeof(linker));
    for(u=1;u<=N;u++){
        memset(used,0,sizeof(used));
        if(dfs(u,limit)) res++;
    }
    return res==N; 
}

//#define LOCAL
int main()
{
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
       #endif
    int T;
    LL X,Y;
    while(scanf("%d",&N)==1){
        init();
        for(int i=1;i<=N;++i)
            scanf("%lld%lld",&s[i].x,&s[i].y);
        for(int i=1;i<=N;++i)
            scanf("%lld%lld",&t[i].x,&t[i].y);
        LL mx=-1;
        for(int i=1;i<=N;++i){
            for(int j=1;j<=N;++j){
                LL dist = abs(s[i].x-t[j].x)+abs(s[i].y-t[j].y);
                AddEdge(i,j+N,dist);
                AddEdge(j+N,i,dist);
                mx = max(mx,dist);
            }
        }
        LL L=0,R=mx,mid;
        while(R-L>1){
            mid = L+(R-L)/2;
            if(hungary(mid)) R = mid;
            else L = mid;
        }
        printf("%lld\n",R);
    }
    return 0;
}

 

posted @ 2018-07-16 21:28  xiuwenL  阅读(307)  评论(0编辑  收藏  举报