洛谷P5030 长脖子鹿放置(二分图+最大独立集)

题目链接:https://www.luogu.com.cn/problem/P5030

提示:二分图最大独立集=点数-最小点覆盖(最大匹配)

题解:这个题其实想想的话可以知道,应该把一些互吃边连在一起建边,把n*n的图划分成一个个的点并标号,有些是陷阱点,所以不用和他进行建边。这样我们能看出来是一个求最大独立集的问题(即二分图相邻2点不连的话最大可包括几个点)。想到了就还挺容易的吧。关于建边其实可以有优化(没有优化也可以过但是浪费时间)。因为我们看到其实其实行是奇数的话,其互吃点必在偶数行,所以可以进一步简化到奇偶边建边(可以省去一半的建边)。而且对于同排多点建边其实你用一个add就可以了,没必要2个add最后除2,亲测有效。

AC100分代码(记得一开始的:不保证禁止放置的格子互不相同。需要去重):

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int tot,head[maxn];
struct E{
    int to,next;
}edge[1000005];
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n,m,k,cnt,used[200*200+5],match[200*200+5];
int find(int x){
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(!used[v]){
            used[v]=true;
            if(!match[v]||find(match[v])){
                match[v]=x;
                return true;
            }
        }
    }
    return false;
}
int a[305][305];
int dx[8]={-3,3,-3,3,-1,1,-1,1};
int dy[8]={1,1,-1,-1,3,3,-3,-3};
int f(int x,int y){
    return (x-1)*m+y;
}
int main(){
    cin>>n>>m>>k;mem(head,-1);
    int cnt=0;
    rep(i,1,k){
        int x,y;cin>>x>>y;
        if(!a[x][y]){
            a[x][y]=1;++cnt;
        }
    }    
    rep(i,1,n){
        rep(j,1,m){
            if(!a[i][j]&&i%2==0){
                rep(k,0,7){
                    int x=i+dx[k],y=j+dy[k];
                    if(x>0&&x<=n&&y>0&&y<=m&&!a[x][y]){
                        add(f(i,j),f(x,y));
                    }
                }
            }
        }
    }
    int ans=0;
    rep(i,1,f(n,m)){
        mem(used,0);
        if(find(i)) ans+=1;
    }
    cout<<n*m-ans-cnt<<endl;    
}
/*
8 7 5
1 1
5 4
2 3
4 7
8 3
*/
View Code
原文地址:https://www.cnblogs.com/Anonytt/p/13355138.html