• 棋盘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
  • 相关阅读:
    webapi 获取json数据
    js的匿名函数与自定义函数
    深入理解计算机系统 第八章 异常控制流(2)
    深入理解计算机系统 第八章 异常控制流(1)
    深入理解计算机系统 第三章 程序的机器级表示(2)
    深入理解计算机系统 第三章 程序的机器级表示(1)
    深入理解计算机系统 第二章 信息的表示和处理(2)
    深入理解计算机系统 第二章 信息的表示和处理(1)
    深入理解计算机系统第一章,计算机系统漫游
    Leetcode练习(Python):第292题:Nim 游戏:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1
  • 原文地址:https://www.cnblogs.com/Rhythm-/p/9395823.html
Copyright © 2020-2023  润新知