码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ AMR12A The Black Riders --二分+二分图最大匹配

时间:2014-07-26 01:24:07      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

题意:有n个人,m个洞。每个洞能容纳一个人,每个人到每个洞需要花费一些时间。每个人到达一个洞后可以花C的时间来挖一个洞,并且最多挖一个洞,这样又能多容纳一人。求能使至少K个人进洞的最短时间。

解法:看到n个人和m个洞,并且人要进洞容易想到二分匹配,又是求极值的问题,应该是最大匹配。由于直接求极值不好求,可以将求极值问题转化为判定问题,即二分最短时间,然后判定能否达到。判定时,如果i到j的时间小于等于mid,就将i和j连一条边,如果T[i][j]+C <= mid 说明还来得及挖洞,将i和j+m连一条边,j+m为新挖的洞,每次判定要建一次图,然后求一个最大匹配,如果最大匹配数>=k,说明mid可行,继续往下二分。直到找到答案。

代码:

bubuko.com,布布扣
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
#define N 107

vector<int> G[N];
int vis[2*N],match[2*N];
int mp[N][N];
int n,m,k,c;

int Search_Path(int s)
{
    for(int i=0;i<G[s].size();i++)
    {
        int v = G[s][i];
        if(!vis[v])
        {
            vis[v] = 1;
            if(match[v] == -1 || Search_Path(match[v]))
            {
                match[v] = s;
                return 1;
            }
        }
    }
    return 0;
}

int Max_match()
{
    memset(match,-1,sizeof(match));
    int cnt = 0;
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(Search_Path(i))
            cnt++;
    }
    return cnt;
}

int check(int mid)
{
    int i,j;
    for(i=0;i<=n;i++)
        G[i].clear();
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            if(mp[i][j] <= mid)
                G[i].push_back(j);
            if(mp[i][j]+c <= mid)
                G[i].push_back(j+m);
        }
    }
    int cnt = Max_match();
    if(cnt >= k)
        return 1;
    return 0;
}

int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d",&n,&m,&k,&c);
        int maxi = -1;
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                scanf("%d",&mp[i][j]);
                maxi = max(mp[i][j],maxi);
            }
        int low = 0;
        int high = maxi;
        while(low<=high)
        {
            int mid = (low+high)/2;
            if(check(mid))
                high = mid-1;
            else
                low = mid+1;
        }
        printf("%d\n",high+1);
    }
    return 0;
}
View Code

 

SPOJ AMR12A The Black Riders --二分+二分图最大匹配,布布扣,bubuko.com

SPOJ AMR12A The Black Riders --二分+二分图最大匹配

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/whatbeg/p/3868930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!