upc6445 棋盘∨

问题 A: 棋盘V

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

题目描述

有一块棋盘,棋盘的边长为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 <bits/stdc++.h>
using namespace std;
const int maxn=4e2+10;
const int inf=0x3f3f3f;
struct node{
    int u,v,cost,cap,flow,next;
}e[maxn*maxn];
int head[maxn],cnt=0;
void add(int u,int v,int cost,int cap,int flow=0){
    e[cnt]=node{u,v,cost,cap,flow,head[u]};
    head[u]=cnt++;
}
int dis[maxn],f[maxn],pre[maxn];
bool vis[maxn];
bool spfa(int s,int t,int &cost,int &flow){
    for (int i=0; i<maxn; i++)
        dis[i]=inf;
    memset(vis,false,sizeof(vis));
    queue<int>q;
    dis[s]=0;
    f[s]=inf;
    q.push(s);
    while(!q.empty()){
        int u=q.front();q.pop();
        for (int i=head[u];i!=-1; i=e[i].next){
            int v=e[i].v;
            vis[u]=false;
            if(e[i].cap>e[i].flow && dis[v]>dis[u]+e[i].cost){
                dis[v]=dis[u]+e[i].cost;
                f[v]=min(f[u],e[i].cap-e[i].flow);
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(dis[t]==inf) return 0;
    cost+=dis[t]*f[t];
    flow+=f[t];
//    for (int i=1; i<10; i++)
//        printf("%d %d\n",dis[i],f[i]);
//    printf("\n");
//    system("pause");
    for (int u=t; u!=s; u=e[pre[u]].u){
        e[pre[u]].flow+=f[t];
        e[pre[u]^1].flow-=f[t];
    }
    return 1;
}
int minCost(int s,int t){
    int cost=0,flow=0;
    while(spfa(s,t,cost,flow));
    return cost;
}
int n,x[maxn],y[maxn],cx[maxn],cy[maxn];
int hax[maxn],hay[maxn],szx,szy;
int mp[maxn][maxn];
 
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for (int i = 1; i <=n ; ++i) {
        scanf("%d%d",&x[i],&y[i]);
        hax[i]=x[i],hay[i]=y[i];
    }
    sort(hax+1,hax+1+n);
    sort(hay+1,hay+1+n);
    szx=unique(hax+1,hax+1+n)-hax-1;
    szy=unique(hay+1,hay+1+n)-hay-1;
    for (int nx,ny,i=1; i<=n; i++){
        nx=lower_bound(hax+1,hax+1+szx,x[i])-hax;
        ny=lower_bound(hay+1,hay+1+szy,y[i])-hay;
        cx[nx]++;
        cy[ny]++;
        mp[nx][ny]=1;
    }
    for (int i=1; i<=szx; i++){
        for (int j=1; j<=szy; j++){
            add(i,j+szx,mp[i][j],1);
            add(j+szx,i,-mp[i][j],0);
        }
    }
    for (int i=1; i<=szx; i++){
        add(0,i,0,cx[i]);
        add(i,0,0,0);
    }
    for (int j=1; j<=szy; j++){
        add(j+szx,szx+szy+1,0,cy[j]);
        add(szx+szy+1,j+szx,0,0);
    }
    long long ans=minCost(0,szx+szy+1);
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2018-08-17 10:31  Acerkoo  阅读(138)  评论(0编辑  收藏  举报