HDU 2236 无题II(二分匹配模板题,匈牙利算法)

来源:互联网 发布:喷涂机器人及软件编程 编辑:程序博客网 时间:2024/05/16 08:44
无题II

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1635    Accepted Submission(s): 751

Problem Description
这是一个简单的游戏,在一个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
 
二分来遍历所有可能的最小差值,二分匹配就是模板题

 

#include <iostream>#include <cstring>using namespace std;const int N = 110;  const int inf = 0x3f3f3f3f;  int num[N],mapp[N][N];int p,mid,n;bool vis[N],flag;bool dfs(int v){    for(int i=0;i<n;i++){        if(mapp[v][i]>=p&&mapp[v][i]<=p+mid&&(!vis[i])){            vis[i]=true;            if(num[i]==-1||dfs(num[i])){                num[i]=v;                return true;            }        }    }    return false;} bool solve(){    memset(num,-1,sizeof(num));    for(int i=0;i<n;i++){        memset(vis,0,sizeof(vis));        if(!dfs(i)){            return false;        }    }    return true;}int main(){    cin.sync_with_stdio(false);    int T;    cin>>T;    while(T--){        cin>>n;        int vmax=-inf,vmin=inf;        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                cin>>mapp[i][j];                vmax=max(vmax,mapp[i][j]);                vmin=min(vmin,mapp[i][j]);            }        }        int r=vmax-vmin,l=0,res;        while(l<=r){            mid=(l+r)>>1;            flag=false;            for(p=vmin;p+mid<=vmax;p++){                if(solve()){                    flag=true;                    break;                }            }            if(flag){                res=mid;                r=mid-1;            }            else{                l=mid+1;            }        }        cout<<res<<endl;    }    return 0;}

2017-02-28 22:06:36
原创粉丝点击