网络流 UVA 12264 Risk
来源:互联网 发布:唱谱软件安卓版 编辑:程序博客网 时间:2024/06/07 23:56
F Risk
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'.
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 in- and output
InputOutput231 1 0NYNYNYNYN77 3 3 2 0 0 5NYNNNNNYNYYNNNNYNYYNNNYYNYNNNNYYNNNNNNNNNYNNNNNYN
14
思路:把每个点拆成两个点,一个入度,一个出度,入度向自己的和每个相邻的点的出度连一条边,容量是ai,每个点出度连一条边到汇点,容量为1,那些与敌人相邻的点再多连一条边到汇点,容量是二分的值,我们只需要二分这个值,跑一下网络流,如果满流,表示可以,否则不行。
代码:
#include <vector>#include <list>#include <map>#include <set>#include <queue>#include <deque>#include <string.h>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#define LL long longusing namespace std;#define eps 1e-7const int maxn=200+5;const int inf=1e8;struct Edge{ int u,v,cap,flow; Edge(int u,int v,int cap,int flow) :u(u),v(v),cap(cap),flow(flow) { }};vector<Edge> edges;vector<int> G[maxn];void add(int u,int v,int cap){ edges.push_back(Edge(u,v,cap,0)); edges.push_back(Edge(v,u,0,0)); int m=edges.size(); G[u].push_back(m-2); G[v].push_back(m-1);}struct ISAP{ int d[maxn], p[maxn], num[maxn], cur[maxn]; int n, s, t; void init(int n) { this->n = n; } int Augment() { int x = t, a = inf; while (x != s) { Edge&e = edges[p[x]]; a = min(a, e.cap - e.flow); x = e.u; } x = t; while (x != s) { edges[p[x]].flow += a; edges[p[x] ^ 1].flow -= a; x = edges[p[x]].u; } return a; } void bfs() { for (int i = 0; i<n; ++i) d[i] = inf; queue<int> q; d[t] = 0; q.push(t); while (q.size()) { int x = q.front(); q.pop(); for (int i = 0; i<G[x].size(); ++i) { Edge&e = edges[G[x][i]]; if (e.cap>0 || d[e.v] <= d[x] + 1) continue; d[e.v] = d[x] + 1; q.push(e.v); } } } int maxflow(int s, int t) { this->s = s, this->t = t; memset(num, 0, sizeof(num)); memset(cur, 0, sizeof(cur)); bfs(); for (int i = 0; i<n; ++i) if (d[i] != inf) ++num[d[i]]; int flow = 0, x = s; while (d[s]<n) { if (x == t) { flow += Augment(); x = s; } int ok = 0; for (int i = cur[x]; i<G[x].size(); ++i) { Edge&e = edges[G[x][i]]; if (e.cap>e.flow&&d[e.v] + 1 == d[x]) { ok = 1; cur[x] = i; p[e.v] = G[x][i]; x = e.v; break; } } if (!ok) { int m = n - 1; for (int i = 0; i<G[x].size(); ++i) { Edge&e = edges[G[x][i]]; if (e.cap>e.flow) m = min(m, d[e.v]); } if (--num[d[x]] == 0) break; ++num[d[x] = m + 1]; cur[x] = 0; if (x != s) x = edges[p[x]].u; } } return flow; }}solver;int n,s,t;bool enm[maxn];int a[maxn];vector<int> bin;int cnt,ctr;inline int in(int x) { return (x<<1)-1; }inline int out(int x) { return x<<1; }void input(){ scanf("%d",&n); memset(enm,0,sizeof(enm)); edges.clear(); s=0; t=2*n+1; solver.init(t+1); for(int i=0;i<maxn;++i) G[i].clear(); ctr=0; for(int i=1;i<=n;++i) { int x; scanf("%d",&x); a[i]=x; if(x==0) enm[i]=true; else { add(s,in(i),x); add(in(i),out(i),x); add(out(i),t,1); ctr++; } } char s[110]; bin.clear(); cnt=0; for(int i=1;i<=n;++i) { scanf("%s",s+1); if(enm[i]) continue; bool near=false; for(int j=1;j<=n;++j) { if(s[j]=='N') continue; if(enm[j]) near=true; else add(in(i),out(j),a[i]); } if(near) { add(out(i),t,inf); int k=edges.size()-2; bin.push_back(k); ++cnt; } }}void clear(int up){ for(int i=0;i<edges.size();++i) edges[i].flow=0; for(int i=0;i<bin.size();++i) { edges[bin[i]].cap=up; }}bool ok(int up){ clear(up); int flow=solver.maxflow(s,t); return (up*cnt+ctr)==flow;}void solve(){ int l=1,r=n*100,m; int ans=0; while(l<=r) { m=(l+r)>>1; if(ok(m)) { ans=m; l=m+1; } else r=m-1; } ++ans; printf("%d\n",ans);}int main(){ int T;cin>>T; while(T--) { input(); solve(); }}
0 0
- 网络流 UVA 12264 Risk
- UVA 12264 Risk 二分最大流
- Risk uva 12264(最大流,二分法,拆点法)
- Uva-12264-Risk
- Risk UVA
- uva 567 risk
- UVA 567 - Risk
- UVA 567 risk FLOYD
- uva 567 Risk
- UVA 567 - Risk
- UVa 567 - Risk
- UVa 567 Risk 解答
- Uva 567 - Risk
- UVa 567 - Risk
- UVa 567: Risk
- UVA - 567 Risk
- UVA 567 - Risk (floyd)
- UVa 567 - Risk(Floyd)
- [学习小结]Ajax_使用 XMLHttpRequest 实现 Ajax
- pull解析细节
- Mysql监控工具Innotop工具安装
- Linux之awk命令
- 蛮力法中的一些排序算法
- 网络流 UVA 12264 Risk
- [Python]核心编程之GUI编程(Tkinter)
- 在Linux下安装FDR
- Ubuntu 14.04 下的MAC OS X 主题安装
- 欢迎进入我的博客
- 求解两个序列的所有最长公共子序列(LCSes)
- Java数据结构_栈
- 杭电ACM 偶数求和
- 机房收费系统——初了解