hdu6808 1007 Go Running 2020杭电多校第4场

http://acm.hdu.edu.cn/showproblem.php?pid=6808

画一个t为x轴,x为y轴的坐标系,由于每个人的速度都是1m/s

那么如果两个点是一个人,那么就要么斜率为1,要么斜率为-1,

这就转换为了经典二分图匹配模型,一个棋盘,要么选一行,要么选一列,最少选多少个占满所有格子,把一个点变成一条边,左右连接1和-1的情况的点,二分图中最小点覆盖=最大匹配

dinic在二分图中跑最大流是m*sqrt(n)的,这里n条边,2*n个点

#include<bits/stdc++.h>
using namespace std;

const int N=8e6,inf=1e9;


int p[N],head[N],nex[N],e=1;
long long c[N],dp[N];
int pos[N],s,t;

void add(int a,int b,int x){
    p[++e]=b;
    nex[e]=head[a];
    head[a]=e;
    c[e]=x;

    p[++e]=a;
    nex[e]=head[b];
    head[b]=e;
    c[e]=0;
}
queue<int>q;


int bfs(){
    int i,u,v;
    for(i=0;i<=t;i++){
        dp[i]=inf;
        pos[i]=head[i];
    }
    dp[s]=0;
    for(q.push(s);q.size();q.pop()){
        u=q.front();
        for(i=head[u];i;i=nex[i]){
            v=p[i];
            if(c[i]&&dp[v]>dp[u]+1){
                dp[v]=dp[u]+1;
                q.push(v);
            }
        }
    }
    return dp[t]!=inf;
}
long long dfs(int u,long long f){
    if(u==t||f==0) return f;
    long long v,k,sum=0;
    for(int &i=pos[u];i;i=nex[i]){
        v=p[i];
        if(c[i]&&dp[v]==dp[u]+1){
            k=dfs(v,min(c[i],f-sum));
            sum+=k;
            c[i]-=k;
            c[i^1]+=k;
            if(sum==f) break;
        }
    }
    return sum;
}
long long maxflow(){
    long long sum=0;
    while(bfs()) sum+=dfs(s,inf);
    return sum;
}




int ha1[N],h1,ha2[N],h2;

int id1(int x){
    return lower_bound(ha1+1,ha1+h1+1,x)-ha1;
}
int id2(int x){
    return lower_bound(ha2+1,ha2+h2+1,x)-ha2;
}


int T[N],X[N];
int main(){
    int i,S,n,m,a,b;
    scanf("%d",&S);
    while(S--){
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d%d",&T[i],&X[i]);
            ha1[i]=X[i]+T[i];
            ha2[i]=X[i]-T[i];
        }
        sort(ha1+1,ha1+1+n);
        sort(ha2+1,ha2+1+n);
        h1=unique(ha1+1,ha1+1+n)-ha1-1;
        h2=unique(ha2+1,ha2+1+n)-ha2-1;

        s=h1+h2+1;
        t=s+1;
        for(i=1;i<=t;i++) head[i]=0;
        e=1;

        for(i=1;i<=h1;i++) add(s,i,1);
        for(i=1;i<=h2;i++) add(h1+i,t,1);
        for(i=1;i<=n;i++){
            a=id1(X[i]+T[i]);
            b=id2(X[i]-T[i]);
            add(a,b+h1,inf);
        }

        printf("%lld\n",maxflow());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107695203