t_t我太弱了這個題都不會做。
反向考慮:
可以把最小問題轉化為最大問題:如果把格仔填滿,我們最多能拿走幾個?
這樣做法就很顯然了。。行列建圖就好了。。qwq
有時候腦子需要拐個彎t_t
#include
#include
#include
#define inf 1000000007
using namespace std;
int n,m,k,sum,cnt=1,s,t,a[105][105],l[105],c[105],sumx[105],sumy[105];
int head[205],cur[205],dis[205],q[205];
intnext[100005],list[100005],key[100005];
inline int
read()
while (c>='0'&&c<='9')
return a*f;
}inline void insert(int
x,int
y,int z)
inline bool bfs()
return dis[t]!=-1;
}int find(int
x,int flow)
if (!used) dis[x]=-1;
return used;
}inline int dinic()
return tmp;
}int main()
}sum=n*m-k; s=0; t=n+m+1;
for (int i=1;i<=n;i++) insert(s,i,l[i]-sumx[i]),insert(i,s,0);
for (int i=1;i<=m;i++) insert(i+n,t,c[i]-sumy[i]),insert(t,i+n,0);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (!a[i][j]) insert(i,j+n,1),insert(j+n,i,0);
cout << sum-dinic() << endl;
return
0;}
BZOJ1458 士兵占領(最大流)
傳送門 判斷joing 的條件是顯然的 如果行或列的總點數減去障礙數還不夠li或ci的話,肯定無解。我的建圖比較奇怪。三排點,分別為每一行,每個點,每一列。s 每一行,li 每一列 t,ci 每一行 當前行中的點,1 每個點 所在的列,1 注意這裡的點必須不是障礙點。最大流即為答案。貼上hzwer的...
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 這一行的障礙格仔數目,即是能夠拿走的士兵數目,然後列向匯點建邊,同理,每乙個格仔 可拿走 ...