傳送門
判斷joing!的條件是顯然的:如果行或列的總點數減去障礙數還不夠li或ci的話,肯定無解。
我的建圖比較奇怪。
三排點,分別為每一行,每個點,每一列。
s->每一行,li
每一列->t,ci
每一行->當前行中的點,1
每個點->所在的列,1
注意這裡的點必須不是障礙點。
最大流即為答案。
貼上hzwer的題解:
此題的思路是先放滿棋盤,然後考慮最多可以刪多少個。。。
某一行和某一列的可以放的格仔數小於需求就直接jiong掉
然後從源向每一行連邊,流量為可以放的格仔數 - 需求的格仔數(也就是可以刪多少格仔)
從每一列向匯,同上.
從每乙個非障礙的格仔的行向列連邊流量為1
跑一遍最大流即可ans=可放格仔數-maxflow
咦怎麼感覺他的更科學。。。
#include
#include
#include
#include
using
namespace
std;
const
int max_n=105;
const
int max_m=105;
const
int max_n=max_n+max_m+max_n*max_m;
const
int max_m=max_n+max_m+max_n*max_m*2;
const
int max_e=max_m*2;
const
int inf=1e9;
int n,m,k,x,y,a[max_n][max_m];
int l[max_n],c[max_m];
int tot,point[max_n],next[max_e],v[max_e],remain[max_e];
int deep[max_n],cur[max_n];
int n,now,maxflow;
queue
q;inline
void addedge(int x,int y,int cap)
inline
bool bfs(int s,int t)
}return deep[t]inline
int dfs(int now,int t,int limit)
}return flow;
}inline
void dinic(int s,int t)
int main()
a[x][y]=1;
}for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
if (!a[i][j])
dinic(1,n);
printf("%d\n",maxflow);
}
BZOJ1458 士兵占領 最大流
time limit 10 sec memory limit 64 mb submit 917 solved 515 submit status discuss 有乙個m n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士...
bzoj1458 士兵占領 最大流
又是反過來考慮。直接計算會很複雜 畢竟每一行和每一列都會有一定的限制條件,很難同時滿足 那麼我們放過來思考,先把所有的各自都放上士兵一共n m k個,然後考慮拿走一部分士兵。源點向每行建邊,邊權是 m l i 這一行的障礙格仔數目,即是能夠拿走的士兵數目,然後列向匯點建邊,同理,每乙個格仔 可拿走 ...
bzoj1458 士兵占領 最大流
time limit 10 sec memory limit 64 mb submit status discuss 有乙個m n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個...