time limit: 10 sec
memory limit: 64 mb [
submit][
status][
discuss]
有乙個m * n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個士兵, 第j列至少放置了cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。
第一行兩個數m, n, k分別表示棋盤的行數,列數以及障礙的個數。 第二行有m個數表示li。 第三行有n個數表示ci。 接下來有k行,每行兩個數x, y表示(x, y)這個格仔是障礙。
輸出乙個數表示最少需要使用的士兵個數。如果無論放置多少個士兵都沒有辦法占領整個棋盤,輸出」jiong!」 (不含引號)
4 4 4
1 1 1 1
0 1 0 3
1 42 2
3 34 3
4資料範圍
m, n <= 100, 0 <= k <= m * n
最少占領
,看起來像是讓我們跑上下界,這等同於最多空出
就沒有了
#include#include#include#define inf 100000000
using namespace std;
const int n = 205;
int last[n*n],h[n*n],q[n*n],d[n*n],ans,cnt=1,t,s=0,n,m,k,l[n*n],ha[n*n],cur[n*n],a[n][n],tot;
struct edgee[210005];
void insert( int u, int v, int w )
bool bfs()
} return h[t] != -1;
}int dfs( int x, int f )
if( !used ) h[x] = -1;
return used;
}void dinic()
}int main()
if( ha[y] < 0 )
} for( int i = 1; i <= m; i++ ) insert( s, i, l[i] );
for( int i = 1; i <= n; i++ ) insert( i+m, t, ha[i] );
for( int i = 1; i <= m; i++ )
for( int j = 1; j <= n; j++ )
if(!a[i][j])
insert( i, j+m, 1 );
dinic();
printf("%d", tot-ans);
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 這一行的障礙格仔數目,即是能夠拿走的士兵數目,然後列向匯點建邊,同理,每乙個格仔 可拿走 ...