首页 > 代码库 > 1458: 士兵占领
1458: 士兵占领
1458: 士兵占领
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1044 Solved: 598
[Submit][Status][Discuss]
Description
有一个M * N的棋盘,有的格子是障碍。现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵。我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵, 第j列至少放置了Cj个士兵。现在你的任务是要求使用最少个数的士兵来占领整个棋盘。
Input
第一行两个数M, N, K分别表示棋盘的行数,列数以及障碍的个数。 第二行有M个数表示Li。 第三行有N个数表示Ci。 接下来有K行,每行两个数X, Y表示(X, Y)这个格子是障碍。
Output
输出一个数表示最少需要使用的士兵个数。如果无论放置多少个士兵都没有办法占领整个棋盘,输出”JIONG!” (不含引号)
Sample Input
4 4 4
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
Sample Output
4
数据范围
M, N <= 100, 0 <= K <= M * N
数据范围
M, N <= 100, 0 <= K <= M * N
HINT
Source
#include<cstdio>#include<cstring>#include<iostream>#define EF if(ch==EOF) return x;using namespace std;const int N=205;const int M=1e5+5;const int inf=2e9;struct edge{int v,next,cap;}e[M<<1];int tot=1,head[N];int n,m,ans,K,S,T,L[N],C[N],G[N],H[N],dis[N<<1],q[M];short mp[N][N];inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;EF;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}void add(int x,int y,int z){ e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;}bool bfs(){ memset(dis,-1,sizeof dis); int h=0,t=1;q[t]=S;dis[S]=0; while(h!=t){ int x=q[++h]; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==-1){ dis[e[i].v]=dis[x]+1; if(e[i].v==T) return 1; q[++t]=e[i].v; } } } return 0;}int dfs(int x,int f){ if(x==T) return f; int used=0,t; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==dis[x]+1){ t=dfs(e[i].v,min(e[i].cap,f)); e[i].cap-=t;e[i^1].cap+=t; used+=t;f-=t; if(!f) return used; } } if(!used) dis[x]=-1; return used;}void dinic(){ ans=0; while(bfs()) ans+=dfs(S,inf);}void work(){ n=read();m=read();K=read();S=0,T=n+m+1; for(int i=1;i<=n;i++) L[i]=read(); for(int i=1;i<=m;i++) C[i]=read(); for(int i=1,x,y;i<=K;i++){ x=read(),y=read(),G[x]++,H[y]++,mp[x][y]=1; if(n-H[y]<C[y]||m-G[x]<L[x]){ printf("JIONG!");return ; } } for(int i=1;i<=n;i++) add(S,i,L[i]); for(int i=1;i<=m;i++) add(i+n,T,C[i]); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(!mp[i][j]){ add(i,j+n,1); } } } dinic(); for(int i=head[S];i;i=e[i].next) ans+=e[i].cap; for(int i=head[T];i;i=e[i].next) ans+=e[i^1].cap; printf("%d",ans);}int main(){ work(); return 0;}
1458: 士兵占领
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。