zoukankan      html  css  js  c++  java
  • hdu 2413(最大匹配+二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2413

    思路:由于要求最少的时间,可以考虑二分,然后就是满足在limit时间下,如果地球战舰数目比外星战舰数目多,就连边,然后求最大匹配即可,判断匹配数目是否等于外星球数目,如果相等,说明可以占领,继续二分。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 #define MAXN 333
     8 #define inf 1<<20
     9 typedef long long ll;
    10 vector<int>map[MAXN];
    11 int mark[MAXN];
    12 int ly[MAXN];
    13 int hp[MAXN],hq[MAXN];
    14 int ap[MAXN],aq[MAXN];
    15 int tt[MAXN][MAXN];
    16 int n,m;
    17 
    18 int dfs(int u)
    19 {
    20     for(int i=0;i<map[u].size();i++){
    21         int v=map[u][i];
    22         if(!mark[v]){
    23             mark[v]=true;
    24             if(ly[v]==-1||dfs(ly[v])){
    25                 ly[v]=u;
    26                 return 1;
    27             }
    28         }
    29     }
    30     return 0;
    31 }
    32 
    33 bool MaxMatch(int limit)
    34 {
    35     for(int i=1;i<=n;i++)map[i].clear();
    36     for(int i=1;i<=n;i++){
    37         for(int j=1;j<=m;j++){
    38             ll t1=1ll+hp[i]+(ll)(limit-tt[i][j])*hq[i];
    39             ll t2=1ll+ap[j]+(ll)limit*aq[j];
    40             if(t1>=t2)map[i].push_back(j);
    41         }
    42     }
    43     int res=0;
    44     memset(ly,-1,sizeof(ly));
    45     for(int i=1;i<=n;i++){
    46         memset(mark,false,sizeof(mark));
    47         res+=dfs(i);
    48     }
    49     if(res==m)return true;
    50     return false;
    51 }
    52 
    53 int main()
    54 {
    55   //  freopen("1.txt","r",stdin);
    56     while(scanf("%d%d",&n,&m),(n+m)){
    57         for(int i=1;i<=n;i++)
    58             scanf("%d%d",&hp[i],&hq[i]);
    59         for(int i=1;i<=m;i++)
    60             scanf("%d%d",&ap[i],&aq[i]);
    61         for(int i=1;i<=n;i++)
    62             for(int j=1;j<=m;j++)
    63                 scanf("%d",&tt[i][j]);
    64         int low=0,high=inf,mid,ans=inf;
    65         while(low<=high){
    66             mid=(low+high)>>1;
    67             if(MaxMatch(mid)){
    68                 ans=mid;
    69                 high=mid-1;
    70             }else
    71                 low=mid+1;
    72         }
    73         if(ans<inf){
    74             printf("%d
    ",ans);
    75         }else
    76             puts("IMPOSSIBLE");
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
  • 原文地址:https://www.cnblogs.com/wally/p/3143463.html
Copyright © 2011-2022 走看看