• hdu 2236(二分图最小点覆盖+二分)


    无题II

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


    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
     
    Author
    xhd
     
    Source
     
    题解:二分枚举差值,然后枚举下界,建造出另一个图,做一次最小点覆盖,如果最小点覆盖值为n,则证明当前差值可行。时间复杂度有点高。。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    const int N = 105;
    int n,MIN,MAX;
    int graph[N][N],mp[N][N];
    int linker[N];
    bool vis[N];
    bool dfs(int u)
    {
        for(int v=1; v<=n; v++)
        {
            if(!vis[v]&&mp[u][v])
            {
                vis[v] = true;
                if(linker[v]==-1||dfs(linker[v]))
                {
                    linker[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    bool match(int mid)
    {
        int k = MAX - mid;
        for(int i=1; i<=k; i++)
        {
            for(int j=1; j<=n; j++)
            {
                for(int k=1; k<=n; k++)
                {
                    if(graph[j][k]<=i+mid&&graph[j][k]>=i) mp[j][k] = 1;
                    else mp[j][k]=0;
                }
            }
            memset(linker,-1,sizeof(linker));
            int res = 0;
            for(int u=1; u<=n; u++)
            {
                memset(vis,false,sizeof(vis));
                if(dfs(u)) res++;
            }
            if(res==n) return true;
        }
        return false;
    }
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        while(tcase--)
        {
            scanf("%d",&n);
            MIN=99999999,MAX=-1;
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    scanf("%d",&graph[i][j]);
                    MIN = min(MIN,graph[i][j]);
                    MAX = max(MAX,graph[i][j]);
                }
            }
            int l = MIN,r = MAX,ans = MAX-MIN;
            while(l<=r)
            {
                int mid = (l+r)>>1;
                if(match(mid))
                {
                    ans = mid;
                    r = mid-1;
                }
                else l=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Unity错误-(Android build error) Can not sign application Unable to sign application; please provide passwords!
    C#WCF中传输List对象
    抓包工具Omnipeek,Wireshark
    Ubuntu18+.netcore+Nginx+Supervisor部署ASP.NET项目
    3D成像技术
    3D显示技术
    学习模电与数电
    【Java123】解决PKIX path building failed / unable to find valid certification path to requested target
    【Python123】Introduction
    【WebConsole123】练习案例之浏览器访问服务器shell
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5716466.html
Copyright © 2020-2023  润新知