BZOJ1458 士兵占領(最大流)

2021-07-10 23:56:41 字數 1472 閱讀 6518

傳送門

判斷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個...