zoukankan      html  css  js  c++  java
  • hdu2336 (匈牙利最大匹配+二分)

    Describe

    这是一个简单的游戏,在一个n*n的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小。

    Input

    输入一个整数T表示T组数据。
    对于每组数据第一行输入一个正整数n(1<=n<=100)表示矩阵的大小。
    接着输入n行,每行n个数x(0<=x<=100)。

    Output

    对于每组数据输出一个数表示最小差值。

    Sample Input

    1
    4
    1 1 1 1
    2 2 2 2
    3 3 3 3
    4 4 4 4
    

    Sample Output

    3
    

    Solution

    首先因为每列每行只能选一个数,自然想到二分图匹配,让行作为左部,列作为右部,让列与行去匹配,当形成完备匹配(左右部点数相等,左部每个点都有对应的匹配点)时,则可取.

    题目中要问最小的极值差,且n范围很小[1,100],所以我们枚举区间len,看看权值在某一区间[ l , l+len ]中的边能否使图形成完备匹配.左端点枚举.对于区间len的大小我们用二分.

    Code

    #include <cmath>
    #include <cstdio>
    #include <cstring> 
    #include <algorithm>
    using namespace std;
    const int maxn=100+5,Inf=0x3f3f3f3f;
    int n,mat[maxn],rel[maxn][maxn],Max,Min;
    bool vis[maxn];
    bool Find(int u,int l,int r){
    	for(int i=1;i<=n;++i){
    		if(rel[u][i]<l||rel[u][i]>r)continue;
    		if(!vis[i]){
    			vis[i]=1;
    			if(!mat[i]||Find(mat[i],l,r)){
    				mat[i]=u;return 1;
    			}
    		}
    	}
    	return 0;
    }
    bool cd(int l,int r){
    	memset(mat,0,sizeof mat);
    	int cnt=0;
    	for(int i=1;i<=n;++i){
    		memset(vis,0,sizeof vis);
    		if(Find(i,l,r))cnt++;
    	}
    	if(cnt==n)return 1;
    	else return 0;
    }
    int main(){
    	int t;scanf("%d",&t);
    	while(t--){
    		Max=0,Min=Inf;
    		scanf("%d",&n);
    		for(int i=1;i<=n;++i){
    			for(int j=1;j<=n;++j){
    				scanf("%d",&rel[i][j]);
    				Max=max(Max,rel[i][j]);
    				Min=min(Min,rel[i][j]);
    			}
    		}
    		int l=0,r=Max-Min,ans=r;//l是区间最小值,r是区间最大值
    		while(l<=r){
    			int mid=((l+r)>>1);//mid是区间长度
    			bool fg=0;
    			for(int i=Min;i+mid<=Max;++i){//枚举左端点
    				if(cd(i,i+mid)){
    					ans=min(ans,mid);
    					fg=1;
    					break;
    				}
    			}
    			if(fg)r=mid-1;
    			else l=mid+1;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/Lour688/p/12885717.html
Copyright © 2011-2022 走看看