BZOJ 1458 士兵占領(網路流)

2022-05-16 04:00:26 字數 1539 閱讀 4745

description

有乙個m * n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個士兵, 第j列至少放置了cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。

solution

可以用上下界最小流來做,不過我覺得黃學長的這個思路也很直接

將每行每列都看成乙個點,由s向行連邊,容量為可以放置的士兵數-至少放置的士兵數

由列向t連邊,容量為可以放置的士兵數-至少放置的士兵數

然後對於每個無障礙的點,由行向列連流量為1的邊

這樣跑最大流就可以得到最多可以刪去多少個士兵啦

#include#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define maxn 105

using

namespace

std;

int s,t,m,n,k,l[maxn],c[maxn],la[maxn],ca[maxn],level[maxn*3],head[maxn*3],cnt=0

;bool

f[maxn][maxn];

struct

node

edges[maxn*maxn*4

];int

read()

while(c>='

0'&&c<='9')

return x*f;

}void addedge(int u,int v,int

w)void insert(int u,int v,int

w)queue

q;bool

bfs()

}if(level[t]==-1)return

false

;

return

true;}

int dfs(int u,int

f) }

if(!flow)level[u]=-1

;

return

flow;

}int

dinic()

return

res;

}int

main()

f[x][y]=1

; }

for(int i=1;i<=m;i++)

for(int j=1;j<=n;j++)

if(!f[i][j])insert(i,m+j,1

);

for(int i=1;i<=m;i++)insert(s,i,la[i]-l[i]);

for(int i=1;i<=n;i++)insert(m+i,t,ca[i]-c[i]);

printf(

"%d\n

",m*n-k-dinic());

return0;

}

bzoj1458 士兵占領 網路流

有乙個m n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個士兵,第j列至少放置了cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。第一行兩個數m,n,k分別表示棋...

bzoj 1458 士兵占領 網路流

description 有乙個m n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個士兵,第j列至少放置了cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。inpu...

BZOJ 1458 士兵占領

time limit 10 sec memory limit 64 mb submit 632 solved 366 submit status discuss description 有乙個m n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不...