zoukankan      html  css  js  c++  java
  • 「SP741」STEAD

    • 前言

      写网络流,因为 rp 过低一直 TLE (悲)。

      结果二分图过了。

      顺手来一发二分图的题解。


    • 题目大意

      农夫约翰的 (N) 头牛各自居住在 (B) 个牛棚之一中。当然,这些牛棚容量有限制。一些牛喜欢它们目前居住的牛棚,另一些并不怎么喜欢。

      约翰想重新安排这些牛,让它们尽可能同样高兴,甚至可以让它们全都讨厌指定的牛棚。

      每头牛给约翰这些牛棚在它们心目中的位置(不会有两个牛棚在某头牛心目中处于同等位置),一头牛的开心值为它所住牛棚在它心目中的位置。

      你的任务就是牛(开心值最大值与最小值之差)的最小值。


    • 分析

      你的任务就是牛(开心值最大值与最小值之差)的最小值。

      这句话很好想到二分

      所以我们可以二分差的最小值,再用 check 函数。

      N头牛各自居住在B个牛棚之一中

      一头牛对应一个牛棚,也就是二分图匹配

      所以,每次二分后,可以枚举每个区间,然后跑二分图匹配,判断匹配数是否为 (n)

      这些牛棚容量有限制。

      一个牛棚可以塞 (b_i) 只牛,换句话说,就是一个牛棚可以匹配 (b_i) 只牛。

      所以在跑二分图匹配的时候,加一个 (cnt_i) 表示(i) 个牛棚已经匹配了 (cnt_i) 只牛

      然后就是二分图操作的时候还要枚举 (cnt_i) 只牛。

      复杂度 (O(n^2m^2log_m))


    • 代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    const int Maxn=1000+5;
    int n,m,ans,mp[Maxn][25],b[Maxn];
    int st,ed,cnt[Maxn],matched[25][Maxn];
    bool vis[Maxn];
    bool found(int x)
    {	
    	for(int i=st;i<=ed;i++)
    	{	
    		int y=mp[x][i];
    		if(vis[y])continue;
    		vis[y]=1;
    		if(cnt[y]<b[y])
    		{	
    			matched[y][++cnt[y]]=x;
    			return 1;
    		}
    		else{
    			for(int j=1;j<=cnt[y];j++)
    				if(found(matched[y][j]))
    				{	
    					matched[y][j]=x;
    					return 1;
    				}
    		}
    	}
    	return 0;
    }
    int match()
    {	
    	int res=0;
    	memset(matched,0,sizeof(matched));
    	memset(cnt,0,sizeof(cnt));
    	for(int i=1;i<=n;i++)
    	{	
    		memset(vis,0,sizeof(vis));
    		if(found(i))res++;
    	}
    	return res;
    }
    bool check(int len)
    {	
    	for(st=1;st<=m;st++)
    	{	ed=st+len-1;
    		if(ed>m)break;
    		if(match()==n)return 1;
    	}
    	return 0;
    }
    int main()
    {	
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			scanf("%d",&mp[i][j]); 
    	for(int i=1;i<=m;i++)
    		scanf("%d",&b[i]);
    	int l=0,r=m,mid;
    	while(l<=r)
    	{	
    		mid=(l+r)>>1;
    		if(check(mid))ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    //沿着风的轨迹 乱舞蹁跹 困于死水之间
    

    [ ext{by Rainy7} ]

  • 相关阅读:
    上周热点回顾(7.29-8.4)团队
    云计算之路:AWS, Azure, Aliyun, UCloud提供的Windows操作系统团队
    上周热点回顾(7.22-7.28)团队
    我的MYSQL学习心得(推荐)
    深度学习笔记之使用Faster-Rcnn进行目标检测 (实践篇)
    深度学习笔记之使用Faster-Rcnn进行目标检测 (原理篇)
    深度学习笔记之基于R-CNN的物体检测
    深度学习笔记之目标检测算法系列(包括RCNN、Fast RCNN、Faster RCNN和SSD)
    深度学习笔记之神经网络、激活函数、目标函数和深度的初步认识
    深度学习笔记之CNN(卷积神经网络)基础
  • 原文地址:https://www.cnblogs.com/Rainy7/p/Steady-Cow-Assignment-solution.html
Copyright © 2011-2022 走看看