题目

Source

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3416

Description

Risk is a board game played on a world map. This world is divided into regions by borders. Each region is controlled by a player (either you or one of your opponents). Any region that you control contains a positive number of your armies.
In each turn, you are allowed to move your armies. Each of your armies may either stay where it is, or move from a region to a bordering region under your control. The movements are performed one by one, in an order of your choice. At all times, each region must contain at least one army.
For strategic purposes, it is important to move your armies to regions that border your opponents’regions and minimize the number of armies on your regions that are totally surrounded by other regions under your control. You want your weakest link, i.e., the border region with the minimum number of armies, to be as strong as possible. What is the maximum number of armies that can be placed on it after one turn?

Input

On the first line a positive integer: the number of test cases, at most 100. After that per test case:
• One line with an integer n (1 ≤ n ≤ 100): the number of regions.
• One line with n integers ai (0 ≤ ai ≤ 100): the number of your armies on each region. A number 0 indicates that a region is controlled by your opponents, while a positive number indicates that it is under your control.
• n lines with n characters, where each character is either ‘Y’ or ‘N’. The i-th character of the j-th line is ‘Y’ if regions i and j border, and ‘N’ otherwise. This relationship is symmetric and the i-th character of the i-th line will always be ‘N’.
In every test case, you control at least one region, and your opponents control at least one region. Furthermore, at least one of your regions borders at least one of your opponents’regions.

Output

Per test case:
• One line with an integer: the maximum number of armies on your weakest border region after one turn of moving

Sample Input

2
3
1 1 0
NYN
YNY
NYN
7
7 3 3 2 0 0 5
NYNNNNN
YNYYNNN
NYNYYNN
NYYNYNN
NNYYNNN
NNNNNNY
NNNNNYN

Sample Output

1
4

分析

题目大概说有N个点,有些被自己占了有些被敌人占了,然后这N个点有几个是相邻的。一开始己方点有几个士兵,一个回合中可以选择某几个己方点的士兵移动到相邻的己方的点,完成移动后要满足所有己方的点至少有一个士兵。问题要的是让边界点(与敌人占的点相邻的自己的点)中的最小值最大。

最小值最大,显然二分。然后就二分+网络流搞了。

值得说的是至少一个士兵的处理,可以直接对于各个点需要几个士兵向汇点连边,即边界点需要二分数值的士兵,而其他需要1个士兵;也可以一开始就把各点的士兵数都-1,也可以;或者最小费用最大流,不过画蛇添足。。

其实这题题目意思感觉不清晰,反正搞过样例就差不多能A了吧。。另外UVa上的样例有点问题,我上面改了。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 222
#define MAXM 222*222 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-1,sizeof(level));
memset(gap,0,sizeof(gap));
level[vt]=0;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-1) continue;
level[v]=level[u]+1;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-1,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=0,aug=INF;
gap[0]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^1].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==0) break;
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
return flow;
} int n,a[111];
char map[111][111]; bool isOK(int k){
vs=0; vt=2*n+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
int tot=0;
for(int i=1; i<=n; ++i){
if(a[i]==0) continue;
addEdge(vs,i,a[i]);
addEdge(i,i+n,INF); bool flag=0;
for(int j=1; j<=n; ++j){
if(map[i][j]=='N') continue;
if(a[j]==0) flag=1;
else addEdge(i,j+n,INF);
} if(flag){
addEdge(i+n,vt,k);
tot+=k;
}else{
addEdge(i+n,vt,1);
++tot;
}
}
return ISAP()==tot;
} int main(){
scanf("%*d");
while(~scanf("%d",&n)){
for(int i=1; i<=n; ++i){
scanf("%d",a+i);
}
for(int i=1; i<=n; ++i){
for(int j=1; j<=n; ++j){
scanf(" %c",&map[i][j]);
}
}
int l=0,r=111111;
while(l<r){
int mid=l+r+1>>1;
if(isOK(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
return 0;
}

UVa12264 Risk(最大流)的更多相关文章

  1. uva12264 Risk

    最小值最大,就二分判断. map[i] = '0'+map[i];这样更方便 每个点拆成i,i’,  S连i,cap为a[i],i’连T,cap为1(保证至少剩一个)或mid. i,i’ ,a[i] ...

  2. Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。

    /** 题目:Risk UVA - 12264 链接:https://vjudge.net/problem/UVA-12264 题意:给n个点的无权无向图(n<=100),每个点有一个非负数ai ...

  3. uva 12264 Risk

    https://vjudge.net/problem/UVA-12264 题意: 有很多个阵地,分为敌方和己方,每个士兵可以移动到相邻的己方的阵地,但是只能移动一步. 现在要让与敌方相邻的阵地中士兵最 ...

  4. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

  5. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  6. FILE文件流的中fopen、fread、fseek、fclose的使用

    FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...

  7. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  8. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

  9. BZOJ 3504: [Cqoi2014]危桥 [最大流]

    3504: [Cqoi2014]危桥 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1407  Solved: 703[Submit][Status] ...

随机推荐

  1. Navicat 回复 psc 文件 Mysql

    在mysql 中回复 psc文件 的时候 只能一步步来,先在navicat中建一个空数据库,然后点击有上角的备份==>回复备份==> 找到psc文件==> 注意此时不要急于点击 开始 ...

  2. XMPP框架下微信项目总结(2)授权登陆/注销/注册/打印日志

    xmpp授权登陆步骤1 初始化xmppstream 连接服务器 传递属性jid(IP地址 端口号)2 连接成功后 传递“登”陆密码授权 3 授权后,发送在线消息xmpp所有的代理都是子线程中调用的,处 ...

  3. Git的一些实用操作

    Ref:http://stackoverflow.com/questions/17195861/undo-git-update-index-assume-unchanged-file 1. 添加本地忽 ...

  4. hdu 4006 The kth great number

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4006 思路:利用优先队列的性质,将数据存入后会自动对数据进行排序 #include<stdlib ...

  5. 三、jQuery--jQuery基础--jQuery基础课程--第6章 jQuery 事件与应用

    1.页面加载时触发ready()事件 ready()事件类似于onLoad()事件,但前者只要页面的DOM结构加载后便触发,而后者必须在页面全部元素加载成功才触发,ready()可以写多个,按顺序执行 ...

  6. bluetooth service uuid

    转自:https://www.bluetooth.com/specifications/assigned-numbers/service-discovery service discovery ​​​ ...

  7. WindowManagerPolicy的后缀 解释

    转自:http://blog.csdn.net/hunanwy/article/details/8563090 Ti,called from the input thread. Input threa ...

  8. 无废话ExtJs 入门教程十三[上传图片:File]

    无废话ExtJs 入门教程十三[上传图片:File] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...

  9. Localstorage本地存储兼容函数

    前言HTML5提供了本地存储的API:localstorage对象和sessionStorage对象,实现将数据存储到用户的电脑上.Web存储易于使用.支持大容量(但非无限量)数据同时存储,同时兼容当 ...

  10. java创建线程的几种方式

    1.继承Thread类 /** * @author Ash * @date: 2016年8月6日 下午10:56:45 * @func: 通过继承Thread类来实现多线程 * @email 4086 ...