问题 A: 棋盘V
时间限制: 1 Sec 内存限制: 128 MB提交: 372 解决: 42
[提交] [状态] [讨论版] [命题人:admin]
题目描述
有一块棋盘,棋盘的边长为100000,行和列的编号为1到100000。棋盘上有n个特殊格子,任意两个格子的位置都不相同。
现在小K要猜哪些格子是特殊格子。她知道所有格子的横坐标和纵坐标,但并不知道对应关系。换言之,她只有两个数组,一个存下了所有格子的横坐标,另一个存下了所有格子的纵坐标,而且两个数组都打乱了顺序。当然,小K猜的n个格子的位置也必须都不相同。
请求出一个最大的k,使得无论小K怎么猜,都能猜对至少k个格子的位置。
现在小K要猜哪些格子是特殊格子。她知道所有格子的横坐标和纵坐标,但并不知道对应关系。换言之,她只有两个数组,一个存下了所有格子的横坐标,另一个存下了所有格子的纵坐标,而且两个数组都打乱了顺序。当然,小K猜的n个格子的位置也必须都不相同。
请求出一个最大的k,使得无论小K怎么猜,都能猜对至少k个格子的位置。
输入
输入数据第一行包含一个整数n。
接下来n行,每行描述一个特殊格子的位置。第i行含有两个整数xi和yi ,代表第i个格子的坐标。保证任意两个格子的坐标都不相同。
接下来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 ",dis[i],f[i]); // printf(" "); // 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 ",ans); return 0; }