zoukankan      html  css  js  c++  java
  • POJ 3189

    题意:

    给你B个谷仓和n头牛,每个谷仓最多容纳m头牛。此时每头牛对每一个谷仓都有一个喜悦值,你需要把每一头牛都安排某个谷仓内,并且找出来那个每一头牛对它所住的谷仓打的分值,我们对这所有的分值取一个区间,使这个区间包含这每一个值。并且尽量使这个区间小一点。

    题解:

    对着区间的两个端点[l,r],先让l==r==1,之后如果在区间[l,r]中分配不成(就使用二分图多重匹配算法来判断)牛群的话就让r++,如果分配成功的话,那么就得让l++

    代码:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<queue>
     6 #include<vector>
     7 using namespace std;
     8 const int maxn=1010;
     9 const int INF=0x3f3f3f3f;
    10 int n,m;
    11 int g[maxn][maxn],mp[maxn][maxn],visit[maxn],match[maxn],link[maxn][maxn];
    12 int cap[maxn],l,r;
    13 int dfs_solve(int u)
    14 {
    15     int v;
    16     for(int v=1;v<=m;v++)
    17     {
    18         if(mp[u][v]<=r && mp[u][v]>=l && !visit[v])
    19         {
    20             visit[v]=1;
    21             if(match[v]<cap[v])
    22             {
    23                 link[v][++match[v]]=u;
    24                 return 1;
    25             }
    26             for(int i=1;i<=cap[v];i++)
    27             {
    28                 if(dfs_solve(link[v][i]))
    29                 {
    30                     link[v][i]=u;
    31                     return 1;
    32                 }
    33             }
    34         }
    35     }
    36     return 0;
    37 }
    38 int hungran()
    39 {
    40     int ans=0;
    41     memset(match,0,sizeof(match));
    42     memset(link,-1,sizeof(link));
    43     for(int i=1;i<=n;++i)
    44     {
    45         memset(visit,0,sizeof(visit));
    46         ans+=dfs_solve(i);
    47     }
    48     return ans;
    49 }
    50 int main()
    51 {
    52     int k,x;
    53     while(~scanf("%d%d",&n,&m))
    54     {
    55         memset(mp,0,sizeof(mp));
    56         for(int i=1;i<=n;++i)
    57         {
    58             for(int j=1;j<=m;++j)
    59             {
    60                 int a;
    61                 scanf("%d",&a);
    62                 mp[i][a]=j;
    63             }
    64         }
    65         for(int i=1;i<=m;++i)
    66             scanf("%d",&cap[i]);
    67         l=r=1;
    68         int ans=INF;
    69         while(l<=r && r<=m)
    70         {
    71             if(hungran()==n)
    72             {
    73                 ans=min(ans,r-l+1);
    74                 l++;
    75             }
    76             else r++;
    77         }
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    poj 3273 Monthly Expense(贪心+二分)
    codeforces 235 div2 C Team
    ZOJ 3607 Lazier Salesgirl(贪心)
    poj 1185 炮兵阵地(三维状态压缩dP)
    poj 2411 Mondriaan's Dream(状态压缩dP)
    sdut 2819 比赛排名(边表 拓扑排序)
    hdu 1421 搬寝室(dp)
    hdu 1243 反恐训练营(dp 最大公共子序列变形)
    Codeforces Round #232 (Div. 2) B. On Corruption and Numbers
    hdu 1559 最大子矩阵 (简单dp)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11493853.html
Copyright © 2011-2022 走看看