匹配問題匯總

來源:互聯網
上載者:User

JOJ 2662: 採購方案 (二分答案+多重匹配)

CCST@JLU 要舉辦這次的程式設計大賽。為了節省開支,在各方面都得考慮仔細,比賽場地布置也不例外。在布置場地時,需要為每台電腦提供電源,由於電腦和電源的位置已經固定,所以要採購一些電源線來串連電腦和電源。kkk在採購時發現,購買相同數量的等長電源線總比購買長度不一的電源線要便宜很多(雖然電源線的價格和長度成正比,卻不影響這個規律:)),所以kkk決定購買相同長度的電源線來布置場地。kkk想節省開支,你能協助他嗎?

 

題解 :二分答案 + 多重匹配,枚舉答案,對小於等於枚舉數的邊加入到網路中看是否可行,可行就繼續找比它小的解 , 不可行就找大一點的解。

 

多重匹配流的構圖,很好想 , 將可多詞匹配的點與源匯的連邊的權值更改成可匹配的次數即可。

#include <cstdio>#include <cstring>#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)const int maxn=800;const int inf = 1<<28;const int s=0 ;struct Edge {    int v,next,w;}edge[maxn*maxn];int head[maxn],cnt;//for sapvoid addedge(int u , int v , int w){    edge[cnt].v=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].v=u;    edge[cnt].w=0;    edge[cnt].next=head[v];    head[v]=cnt++;}int n,m,cc;///int sap(int t){    int pre[maxn],cur[maxn];    int dis[maxn],gap[maxn];    int flow=0 , aug=inf ,u;    bool flag;    for (int i=0 ; i<=t ; ++i)    {        cur[i]=head[i];        gap[i]=dis[i]=0;    }    gap[s]=t+1;    u=pre[s]=s;    while (dis[s]<=t)    {          flag=0 ;          for (int &j=cur[u] ; ~j ; j=edge[j].next)          {              int v=edge[j].v;              if (edge[j].w>0 && dis[u]==dis[v]+1)              {                   flag=1;                   if(edge[j].w<aug)aug=edge[j].w;                   pre[v]=u;                   u=v;                   if (u==t)                   {                       flow+=aug;                       while (u!=s)                       {                             u=pre[u];                             edge[cur[u]].w-=aug;                             edge[cur[u]^1].w+=aug;                       }                       aug=inf;                   }                   break;              }          }          if (flag)continue ;          int mindis=t+1;          for (int j=head[u]; ~j ; j=edge[j].next)          {              int v=edge[j].v;              if (edge[j].w>0 && dis[v]<mindis)              {                 mindis=dis[v];                 cur[u]=j;              }          }          if(--gap[dis[u]]==0)break;          gap[dis[u]=mindis+1]++;          u=pre[u];    }    return flow;}int map[maxn][maxn];int c[maxn];int main (){    int cas;    scanf("%d",&cas);    while (cas--)    {        scanf("%d%d%d",&n,&m,&cc);        for (int i=0 ; i<n ; ++i)        {            for (int j=0 ; j<m ; ++j)            {                scanf("%d",map[i]+j);            }        }        int sum=0;        for (int i=0 ; i<m ; ++i)        {            scanf("%d",c+i);            sum+=c[i];        }        if(sum<n){puts("-1"); continue;}        int ans=inf;        int l=0,r=10000;        ///        while (l<=r)        {            int mid=(l+r)>>1;            memset (head , -1 , sizeof(head));            cnt=0;            for (int i=0 ; i<n ; ++i)            {                addedge (0 , i+1 , 1);                for (int j=0 ; j<m ; ++j)                {                    if(map[i][j]<=mid)                    {                        addedge(i+1,j+n+1,1);                    }                }            }            for (int j=0 ; j<m ; ++j)                addedge(j+n+1 , n+m+1 , c[j]);            int match;            match=sap(n+m+1);            //printf("match = %d\n",match);            if(n==match)            {                r=mid-1;                ans=min(ans,mid);            }            else l=mid+1;        }        printf("%d\n",ans*cc*n);    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.