BZOJ P2150 部落战争

清明节也不能懈怠

虽然已经打了好久了隔膜了

但是你说不做题目也是不行的啊

今天学了一个公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数.

感觉网上的证明也不太好,yy了一下自己的证明

我的证明是这样的:

。。。。。。。。

先说怎么做

直接每个DAG上的点拆点然后建二分图,原点和S连,然后拆出的点和T连跑最大匹配

然后我们可以发现,DAG上的某一条路可以对应一个所建的二分图中的一个匹配

同时可以得出一个公式  DAG路径覆盖可以=对应二分图中的某一个匹配

然后我要证   DAG路径覆盖数=DAG图中的节点数-对应二分图中的某一个匹配

是这样的,我假设一条路径是a->b,b->c,c->d对应的二分图上是a->b拆出来的点,b->c拆出来的点,c->d拆出来的点

然后相当于原图上每一条路径假设包含n个点,那么就是在图上的n-1个匹配

所以每一条路径的产生,二分图匹配就会拆一个点,所以DAG路径覆盖可以=对应二分图中的某一个匹配

然后我们要求的是DAG的最小路径覆盖数

只要二分图中的匹配数最大即可

证明完毕,不知道有没有什么疏漏有的请帮忙讲出


然后知道了以上几点,很容易做这题了,就是构图跑最大匹配然后减一减就可以辣

下面是代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 2503
using namespace std;
int a[2503][2503],lk[2503],f[2503][2503],num[2503][2503];
int  vis[2503];
int dx[5],dy[5];
char s[503];
int n,m,r,c,sum,ans,id;
int tim;
bool find(int x){
	for(int i=1;i<=id;i++){
		if(a[x][i]&&vis[i]!=tim){
        	vis[i]=tim;
        	if(!lk[i]||find(lk[i])){
            	lk[i]=x;
            	return 1;
        	}
      	}
	}
    return 0;
}
int main(){
    cin>>n>>m>>r>>c;
    id=0;
    for(int i=1;i<=n;i++){
        cin>>s;
        for(int j=0;j<m;j++){
        	if(s[j]=='.'){
        		f[i][j+1]=1,num[i][j+1]=++id;
			}else{
				f[i][j+1]=0;
			}
		}
    }
    dx[0]=r;  dx[1]=r;   dx[2]=c;  dx[3]=c;
    dy[0]=c;  dy[1]=-c;  dy[2]=r;  dy[3]=-r;
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		if(f[i][j]){
        		for(int k=0;k<4;k++){
            		int x=i+dx[k],y=j+dy[k];
            		if(x<1||x>n||y<1||y>m){
            			continue;
					}
            		if(f[x][y]){
            			a[num[i][j]][num[x][y]]=1;
					}
        		}
			}
		}
        
	}
    for (int i=1;i<=id;i++){
        tim++;
        if(find(i)){
        	ans++;
		}
    }
    cout<<(id-ans)<<endl;
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值