TLE 72分 Dinic求助

P3355 骑士共存问题

KarmaticEnding @ 2024-09-30 11:49:43

关于本题,我的思路是网络流最大流实现二分图,但是第三个点显示 \text{TLE},本人在本地测的时候并不是跑不出来,而是运行时间高达 9 秒,请问各位大佬这怎么办?

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10,MAXM=4e5+10;
const int s=1e5+8,t=1e5+9,INF=1e5;
int dis[MAXN],cur[MAXN];
queue<int> q;
int h[MAXN],e[MAXM],c[MAXM],nxt[MAXM],idx=0;
int ans=0;
int n,m;
bool isobs[256][256];//是障碍
const int p[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{2,-1},{2,1},{1,-2},{1,2}};
inline int pos(int x,int y){
    return (x-1)*n+y;
}
inline void add(int u,int v,int _c){
    e[idx]=v;
    c[idx]=_c;
    nxt[idx]=h[u];
    h[u]=idx;
    ++idx;
}
bool BFS(){
    while(q.size()){
        q.pop();
    }
    memset(dis,-1,sizeof(dis));
    dis[s]=0;
    q.push(s);
    cur[s]=h[s];
    while(q.size()){
        int u=q.front();
        q.pop();
        for(int i=h[u];~i;i=nxt[i]){
            int v=e[i];
            if(dis[v]==-1&&c[i]>0){
                dis[v]=dis[u]+1;
                q.push(v);
                cur[v]=h[v];
                if(v==t){
                    return true;
                }
            }
        }
    }
    return false;
}
int _find_(int u,int limit){
    if(u==t){
        return limit;
    }
    int flow=0;
    for(int i=cur[u];~i;i=nxt[i]){
        cur[u]=i;
        int v=e[i];
        if(dis[v]==dis[u]+1&&c[i]>0){
            int tf=_find_(v,min(c[i],limit-flow));
            if(tf==0){
                dis[v]=-1;
            }
            c[i]-=tf;
            c[i^1]+=tf;
            flow+=tf;
        }
    }
    return flow;
}
int Dinic(){
    int res=0,flow;
    while(BFS()){
        flow=_find_(s,INF);
        while(flow){
            res+=flow;
            flow=_find_(s,INF);
        }
    }
    return res;
}
int main(){
    memset(h,-1,sizeof(h));
    scanf("%d%d",&n,&m);//n×n,m个障碍
    ans=n*n;
    for(int i=1,x,y;i<=m;++i){
        scanf("%d%d",&x,&y);
        isobs[x][y]=true;
        --ans;
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(isobs[i][j]){
                continue;
            }
            if((i+j)&1){
//              printf("(%d,%d):left\n",i,j);
                add(s,pos(i,j),1);
                add(pos(i,j),s,0);
            }
            else{
//              printf("(%d,%d):right\n",i,j);
                add(pos(i,j),t,1);
                add(t,pos(i,j),0);
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(((i+j)&1)&&(!isobs[i][j])){
                for(int k=0;k<8;++k){
                    int x=i+p[k][0],y=j+p[k][1];
                    if(x<=0||y<=0||x>n||y>n||isobs[x][y]){
                        continue;
                    }
                    add(pos(i,j),pos(x,y),1);
                    add(pos(x,y),pos(i,j),0);
//                  printf("(%d,%d)->(%d,%d)\n",i,j,x,y);
                }
            }
        }
    }
    printf("%d",ans-Dinic());
    return 0;
}

|