zoukankan      html  css  js  c++  java
  • 棋盘V

    问题 A: 棋盘V

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 150  解决: 3
    [提交] [状态] [讨论版] [命题人:]

    题目描述

    有一块棋盘,棋盘的边长为100000,行和列的编号为1到100000。棋盘上有n个特殊格子,任意两个格子的位置都不相同。
    现在小K要猜哪些格子是特殊格子。她知道所有格子的横坐标和纵坐标,但并不知道对应关系。换言之,她只有两个数组,一个存下了所有格子的横坐标,另一个存下了所有格子的纵坐标,而且两个数组都打乱了顺序。当然,小K猜的n个格子的位置也必须都不相同。
    请求出一个最大的k,使得无论小K怎么猜,都能猜对至少k个格子的位置。

    输入

    输入数据第一行包含一个整数n。
    接下来n行,每行描述一个特殊格子的位置。第i行含有两个整数xi和yi ,代表第i个格子的坐标。保证任意两个格子的坐标都不相同。 

    输出

    输出一行,包含一个整数,代表最大的k。

    样例输入

    2
    1 1
    2 2
    

    样例输出

    0
    

    提示

    小K有可能会猜(1,2),(2,1),此时一个都没对
    对于30%的数据,n≤8。
    另外有5%的数据,所有横坐标和纵坐标均不相同。
    另外有15%的数据,所有横坐标或者纵坐标均不相同。
    对于100%的数据,n≤50,1≤xi,yi≤100000。

    分析:费用流板子题,从裤裆里掏出费用流板子,魔改了两小时,终于能跑了。不说了,自闭了。
    #include <iostream>
    #include <string>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <map>
    #define LL long long
    #define equal ==
    #define inf 0x3f3f3f3f
    #define fr first
    #define sc second
    #define range(i,a,b) for(auto i=a;i<=b;++i)
    #define itrange(i,a,b) for(auto i=a;i!=b;++i)
    #define rerange(i,a,b) for(auto i=a;i>=b;--i)
    #define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
    using namespace std;
    const int mxn=int(1e5+5);
    int n,x[mxn],y[mxn],p[mxn],cnt,flag[1005][1005],ans;
    namespace MCMF{
        struct edge{
            int head,to,nxt,cost,weight;
        }edges[mxn];
        bool vis1[mxn],vis2[mxn];
        int S,T,sum1[mxn],sum2[mxn],d[mxn],tol=2;
        void add(int x,int y,int z,int p){
            edges[tol].cost=p;edges[tol+1].cost=-p;
            edges[tol].weight=z;edges[tol+1].weight=0;
            edges[tol].to=y;edges[tol+1].to=x;
            edges[tol].nxt=edges[x].head;edges[tol+1].nxt=edges[y].head;
            edges[x].head=tol++;edges[y].head=tol++;
        }
        bool spfa(){
            fill(vis1,0);fill(vis2,0);fill(d,inf);
            queue<int>q;
            q.push(S);
            d[S]=0;
            vis1[S]=1;
            while(not q.empty()){
                int head=q.front();
                q.pop();
                vis1[head]=false;
                for(int i=edges[head].head;i;i=edges[i].nxt){
                    int to=edges[i].to;
                    if(edges[i].weight and d[to]>d[head]+edges[i].cost){
                        d[to]=d[head]+edges[i].cost;
                        if(!vis1[to]){
                            vis1[to]=true;
                            q.push(to);
                        }
                    }
                }
            }
            return d[T]!=inf;
        }
        int dfs(int to,int fs){
            if(to equal T){
                ans+=d[to]*fs;
                return fs;
            }
            int ret=0;
            vis2[to]=true;
            for(int i=edges[to].head;i;i=edges[i].nxt){
                int tmp=edges[i].to;
                if(edges[i].weight and not vis2[tmp] and d[tmp] equal d[to]+edges[i].cost){
                    int ntmp(dfs(tmp,min(fs-ret,edges[i].weight)));
                    edges[i].weight-=ntmp;
                    edges[i^1].weight+=ntmp;
                    ret+=ntmp;
                    if(ret==fs)return ret;
                }
            }
            return ret;
        }
    }
    void init(){
        scanf("%d",&n);
        MCMF::S=(n<<2)+1;
        MCMF::T=MCMF::S+1;
        range(i,1,n){
            scanf("%d%d",x+i,y+i);
            p[++cnt]=*(x+i);
            p[++cnt]=*(y+i);
        }
        sort(p+1,p+1+cnt);
        cnt=int(unique(p+1,p+1+cnt)-p-1);
        range(i,1,n){
            x[i]=int(lower_bound(p+1,p+1+cnt,x[i])-p);
            y[i]=int(lower_bound(p+1,p+1+cnt,y[i])-p);
            using namespace MCMF;
            ++sum1[x[i]];
            ++sum2[y[i]];
            flag[x[i]][y[i]]=true;
        }
    }
    void solve(){
        using namespace MCMF;
        range(i,1,cnt){
            if(sum1[i])add(S,i,sum1[i],0);
            if(sum2[i])add(i+(n<<1),T,sum2[i],0);
        }
        range(i,1,cnt)
        range(j,1,cnt){
            if(flag[i][j])add(i,j+(n<<1),1,1);
            else add(i,j+(n<<1),1,0);
        }
        while(spfa())dfs(S,inf);
        printf("%d
    ",ans);
    }
    int main() {
        init();
        solve();
        return 0;
    }
    View Code
  • 相关阅读:
    Ftp、Ftps与Sftp之间的区别
    Previous Workflow Versions in Nintex Workflow
    Span<T>
    .NET Core 2.0及.NET Standard 2.0 Description
    Announcing Windows Template Studio in UWP
    安装.Net Standard 2.0, Impressive
    SQL 给视图赋权限
    Visual Studio for Mac中的ASP.NET Core
    How the Microsoft Bot Framework Changed Where My Friends and I Eat: Part 1
    用于Azure功能的Visual Studio 2017工具
  • 原文地址:https://www.cnblogs.com/Rhythm-/p/9395823.html
Copyright © 2011-2022 走看看