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的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不...