题意:有一个数轴,若干人在某个时刻开始从某个点朝某个方向按 1 1 1的速度走若干时间。已知 n n n个条件,形如 t i t_i ti时刻 x i x_i xi的位置有人,求最少可能的人数。
∑ n ≤ 5 × 1 0 5 \sum n\leq 5\times 10^5 ∑n≤5×105
画出 x − t x-t x−t二维平面,可以看成用最少 k = ± 1 k=\pm1 k=±1的直线覆盖给出的 n n n个点
转 45 ° 45\degree 45°看成水平线或竖直线(但好像没啥区别)
过每个点作水平线和竖直线,将直线去重,然后直线建成点,点建成过它作的两个直线之间连的边,跑最小点覆盖即可。
注意匈牙利是 O ( n m ) O(nm) O(nm),dinic只有 O ( m n ) O(m\sqrt n) O(mn)
#include
#include
#include
#include
#include
#define MAXN 200005
#define MAXM 400005
#define INF 0x3f3f3f3f
using namespace std;
struct edge{int u,v,c;}e[MAXM];
int head[MAXN],nxt[MAXM],cnt;
void ins(int u,int v,int c)
{
e[++cnt]=(edge){u,v,c};
nxt[cnt]=head[u];
head[u]=cnt;
}
void addnode(int u,int v,int c){ins(u,v,c);ins(v,u,0);}
int s,t;
int dis[MAXN];
bool bfs()
{
queue<int> q;
q.push(s);
memset(dis,-1,sizeof(dis));
dis[s]=0;
while (!q.empty())
{
int u=q.front();
q.pop();
for (int i=head[u];i;i=nxt[i])
if (e[i].c&&dis[e[i].v]==-1)
{
dis[e[i].v]=dis[u]+1;
q.push(e[i].v);
if (e[i].v==t)
return true;
}
}
return false;
}
int dfs(int u,int f)
{
if (u==t||!f)
return f;
int used=0;
for (int i=head[u];i;i=nxt[i])
if (e[i].c&&dis[e[i].v]==dis[u]+1)
{
int w=dfs(e[i].v,min(e[i].c,f));
if (!w)
continue;
used+=w;
e[i].c-=w;
e[i^1].c+=w;
f-=w;
if (used==0)
break;
}
if (!used) dis[u]=-1;
return used;
}
int dinic()
{
int mflow=0;
while (bfs())
mflow+=dfs(s,INF);
return mflow;
}
int x[MAXN],y[MAXN],xl[MAXN],yl[MAXN],xcnt,ycnt;
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n;
scanf("%d",&n);
for (int i=1;i<=xcnt+ycnt+2;i++) head[i]=0;
for (int i=1;i<=cnt;i++) nxt[i]=0;
cnt=1,xcnt=ycnt=0;
for (int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
x[i]=xl[i]=a+b;
y[i]=yl[i]=a-b;
}
sort(xl+1,xl+n+1);
xcnt=unique(xl+1,xl+n+1)-xl-1;
sort(yl+1,yl+n+1);
ycnt=unique(yl+1,yl+n+1)-yl-1;
s=xcnt+ycnt+1,t=s+1;
for (int i=1;i<=xcnt;i++) addnode(s,i,1);
for (int i=xcnt+1;i<=xcnt+ycnt;i++) addnode(i,t,1);
for (int i=1;i<=n;i++)
{
x[i]=lower_bound(xl+1,xl+xcnt+1,x[i])-xl;
y[i]=lower_bound(yl+1,yl+ycnt+1,y[i])-yl;
addnode(x[i],y[i]+xcnt,1);
}
printf("%d\n",dinic());
}
return 0;
}