https://vjudge.net/problem/UVA-12264

题意:

有很多个阵地,分为敌方和己方,每个士兵可以移动到相邻的己方的阵地,但是只能移动一步。

现在要让与敌方相邻的阵地中士兵最少的最多。

思路:

最少的最多,那显然二分。

二分这个最少的值。拆点,敌方阵地不管,S向己方阵地\(i\)向连边,容量为本阵地士兵的数量,\(i'\)向T连边,如果是与敌方相邻的阵地,那么容量为二分的值;如果是处于己方阵地的包围,那么容量为1即可。最后跑最大流判断是否满流。

STD:

本STD在uva上AC,uvalive上WA,请谨慎食用。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 205;
int a[N];
char s[N][N];
bool is[N]; struct edge
{
int u,v,cap;
edge(int u,int v,int cap):u(u),v(v),cap(cap){}
edge(){}
}; vector<edge> es;
vector<int> G[N];
int n,S,T;
int dis[N],cur[N]; void adde(int u,int v,int cap)
{
es.push_back(edge(u,v,cap));
es.push_back(edge(v,u,0));
int sz = es.size();
G[u].push_back(sz-2);
G[v].push_back(sz-1);
} bool bfs()
{
memset(dis,inf,sizeof dis);
dis[S] = 0;
queue<int> q;
q.push(S);
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0;i < G[u].size();i++)
{
edge &e = es[G[u][i]];
int v = e.v;
if (e.cap > 0 && dis[v] >= inf)
{
dis[v] = dis[u] + 1;
q.push(v);
}
}
}
return dis[T] < inf;
} int dfs(int u,int flow)
{
if (u == T) return flow;
for (int i = cur[u];i < G[u].size();i++)
{
cur[u] = i;
edge &e = es[G[u][i]];
int v = e.v;
if (dis[v] == dis[u] + 1 && e.cap > 0)
{
int tmp = dfs(v,min(e.cap,flow));
if (tmp)
{
e.cap -= tmp;
es[G[u][i]^1].cap += tmp;
return tmp;
}
}
}
return 0;
} int dinic()
{
int ans = 0;
while (bfs())
{
int tmp;
memset(cur,0,sizeof(cur));
while (tmp = dfs(S,inf)) ans += tmp;
}
return ans;
} bool meet(int lim)
{
for (int i = 0;i < N;i++) G[i].clear();
es.clear();
for (int i = 1;i <= n;i++)
{
if (a[i] <= 0) continue;
adde(S,i,a[i]);
adde(i,i+n,inf);
}
int sum = 0;
for (int i = 1;i <= n;i++)
{
if (a[i] <= 0) continue;
if (is[i])
{
sum += lim;
adde(i+n,T,lim);
}
else
{
sum++;
adde(i+n,T,1);
}
}
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= n;j++)
{
if (i == j) continue;
if (a[i] <= 0 || a[j] <= 0) continue;
if (s[i][j] == 'Y')
{
adde(i,j+n,inf);
}
}
}
int ans = dinic();
return ans >= sum;
} int main()
{
int t;
scanf("%d",&t);
while (t--)
{
memset(is,0,sizeof is);
scanf("%d",&n);
S = 0;
T = 2 * n + 1;
for (int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
}
for (int i = 1;i <= n;i++)
{
scanf("%s",s[i]+1);
}
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= n;j++)
{
if (a[i] > 0 && a[j] <= 0)
{
if (s[i][j] == 'Y') is[i] = true;
}
}
}
int l = 1,r = 1e5;
while (r - l > 1)
{
int mid = (l + r) >> 1;
if (meet(mid)) l = mid;
else r = mid;
}
while (meet(l+1)) l++;
printf("%d\n",l);
}
return 0;
} /*
3
1 1 0
NYN
YNY
NYN
7
7 3 3 2 0 0 5
NYNNNNN
YNYYNNN
NYNYYNN
NYYNYNN
NNYYNNN
NNNNNNY
NNNNNYN
4
2 2 0 0
NNYN
NNNY
YNNN
NYNN
*/

最新文章

  1. 【先定一个小目标】怎么解决mysql不允许远程连接的错误
  2. ASP.NET Web API 接口执行时间监控
  3. [Web API] Web API 2 深入系列(4) Action的选择
  4. MongoDB学习:(二)MongoDB简单使用
  5. webrtc第二篇 聊天室
  6. HDU-4525 威威猫系列故事——吃鸡腿
  7. HTML5全局属性和事件
  8. ssh框架整合---- spring 4.0 + struts 2.3.16 + maven ss整合超简单实例
  9. 怎么实现form表单提交后不重新刷新当前页面
  10. Python之路【第五篇】:面向对象及相关
  11. 【百度地图API】JS版本的常见问题
  12. 《openstack 和hadoop的区别是什么?》
  13. 用static关键字修饰类
  14. Less基础教程
  15. itext之pdf导出添加水印Java工具类
  16. asp.net core mvc剖析:路由
  17. c#之依赖注入
  18. Cisco端口限速配置
  19. 第四章 jQuery节点操作
  20. python全栈开发笔记---------字符串格式化

热门文章

  1. uni-app 实现热更新
  2. PTA --- L2-003 月饼
  3. python基础知识(循环语句)
  4. Django:(02)项目配置
  5. idea标签页多行显示+设置标签页上限
  6. ASP.NET Core 入门笔记8,ASP.NET Core MVC 分部视图入门
  7. 产品之我见(3)-ZEN在产品上的延伸
  8. kubenetes 的svc从ClusterPort 改为NodePort
  9. (模板)luoguP3806(树上点分治模板题)
  10. 14.Sqoop把数据从HDFS导出到mysql