/**
题目:Risk UVA - 12264
链接:https://vjudge.net/problem/UVA-12264
题意:给n个点的无权无向图(n<=100),每个点有一个非负数ai。
若ai==0则此点归敌方所有,若ai>0则此点归你且上面有ai个属于你的士兵。
保证至少有一个属于你的点与敌方的点相邻。你可以让你的每个士兵最多移动一次
,每次可以待在原地或者去到相邻的属于你的领地,但每个点至少要留1各士兵,
使得最薄弱的关口尽量坚固。关口是指与敌方点相邻的点,薄弱与坚固分别指兵少与兵多。 思路:拆点法+最大流+二分。 将点x,拆分成x,x'。
s->x,容量为初始士兵数量。
x'->t。 如果x是薄弱点,那么容量为mid,否则容量为1。1是为了满足题目至少留一个兵。
x->x',容量为INF。 如果x与y相邻,x->y',容量为INF。 上面的容量为mid,就是假如所有的薄弱点都为mid个士兵,是否可行,如果可行,那么增加mid,找一个满足的最大的mid。 二分mid。 如果最大流=薄弱点数量*mid+(自己的领地结点数-薄弱点数量)*1。那么可行。 注意:原题题意给出的输入输出要求是没有问题的,不过题目的实际输入输出有点问题。照着题意要求做就行。 */
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const long long MAS = 1e13;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int N = ;///拆点法,注意要乘以个2.
struct Edge{
int from, to, cap, flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[N];
bool vis[N];
int d[N];
int cur[N]; void init(int n)
{
this->n = n;
for(int i = ; i <= n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
memset(vis, , sizeof vis);
queue<int> Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while(!Q.empty())
{
int x = Q.front();
Q.pop();
for(int i = ; i < G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to] = ;
d[e.to] = d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t||a==) return a;
int flow = , f;
for(int &i = cur[x]; i < G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
e.flow += f;
edges[G[x][i]^].flow -= f;
flow += f;
a -= f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s = s, this->t = t;
int flow = ;
while(BFS())
{
memset(cur, , sizeof cur);
flow += DFS(s,INF);
}
return flow;
}
};
char str[N][N];
int sd[N], f[N][N];
int weak[N], enemy[N];
int main()
{
int n, k;
cin>>k;
while(k--){
scanf("%d",&n);
memset(enemy, , sizeof enemy);
for(int i = ; i <= n; i++){
scanf("%d",&sd[i]);
if(sd[i]==) enemy[i] = ;///敌人结点
}
memset(f, , sizeof f);
memset(weak, , sizeof weak);
for(int i = ; i <= n; i++){
scanf("%s",str[i]+);
for(int j = ; j <= n; j++){
if(str[i][j]=='Y'){
f[i][j] = ;
if(enemy[i]&&enemy[j]==){
weak[j] = ;///薄弱结点
}
if(enemy[i]==&&enemy[j]){
weak[i] = ;///薄弱结点
}
}
}
}
int s = , t = n*+;
Dinic dinic, save;
dinic.init(t);
for(int i = ; i <= n; i++){
if(enemy[i]) continue;
dinic.AddEdge(s,i,sd[i]);
dinic.AddEdge(i,i+n,INF);
if(weak[i]==){
dinic.AddEdge(i+n,t,);
}
}
for(int i = ; i <= n; i++){
if(enemy[i]) continue;
for(int j = ; j <= n; j++){
if(enemy[j]) continue;
if(f[i][j]){
dinic.AddEdge(i,j+n,INF);
}
}
} save = dinic;
int weaknum = , total = ;
for(int i = ; i <= n; i++){
if(weak[i]) weaknum++;
if(enemy[i]==) total++;
}
int lo = , hi = INF, mid;
int ans;
while(lo<=hi){
mid = (lo+hi)/;
dinic = save;
for(int i = ; i <= n; i++){
if(weak[i]){
dinic.AddEdge(i+n,t,mid);
}
}
int mas = dinic.Maxflow(s,t);
int sum = weaknum*mid+(total-weaknum);
if(mas==sum){
lo = mid+;
ans = mid;
}else
{
hi = mid-;
}
}
printf("%d\n",ans);
}
return ;
}

Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。的更多相关文章

  1. Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负

    /** 题目:Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负 链接:https://vjudge.net/problem/UVA-1161 ...

  2. UVa 1658 (拆点法 最小费用流) Admiral

    题意: 给出一个有向带权图,求从起点到终点的两条不相交路径使得权值和最小. 分析: 第一次听到“拆点法”这个名词. 把除起点和终点以外的点拆成两个点i和i',然后在这两点之间连一条容量为1,费用为0的 ...

  3. UVA 1658 海军上将(拆点法+最小费用限制流)

    海军上将 紫书P375 这题我觉得有2个难点: 一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点. 二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制 ...

  4. poj3422 拆点法x->x'建立两条边+最小费用最大流

    /** 题目:poj3422 拆点法+最小费用最大流 链接:http://poj.org/problem?id=3422 题意:给定n*n的矩阵,含有元素值,初始sum=0.每次从最左上角开始出发,每 ...

  5. UVA1658 Admiral 拆点法解决结点容量(路径不能有公共点,容量为1的时候) 最小费用最大流

    /** 题目:UVA1658 Admiral 链接:https://vjudge.net/problem/UVA-1658 题意:lrj入门经典P375 求从s到t的两条不相交(除了s和t外,没有公共 ...

  6. 紫书 习题 11-4 UVa 1660 (网络流拆点法)

    这道题改了两天-- 因为这道题和节点有关, 所以就用拆点法解决节点的容量问题. 节点拆成两个点, 连一条弧容量为1, 表示只能经过一次. 然后图中的弧容量无限. 然后求最小割, 即最大流, 即为答案. ...

  7. uva 1658(最小费用最大流)

    题意:一个带权有向图,求起点到终点的两条路径权值之和最小,且两条路径没有公共点(除起点,终点): 分析:拆点法,将u拆成u和u',u-u'容量为1,费用为0,这样就能保证每个点只用一次,起点s-s'容 ...

  8. UVA1349 Optimal Bus Route Design 拆点法+最小费用最佳匹配

    /** 题目:UVA1349 Optimal Bus Route Design 链接:https://vjudge.net/problem/UVA-1349 题意:lrj入门经典P375 给n个点(n ...

  9. hdu4289 最小割最大流 (拆点最大流)

    最小割最大流定理:(参考刘汝佳p369)增广路算法结束时,令已标号结点(a[u]>0的结点)集合为S,其他结点集合为T=V-S,则(S,T)是图的s-t最小割. Problem Descript ...

随机推荐

  1. Oracle 命令导入数据

    1.用命令进入sqlplus: sqlplus 用户名:/orcl 2.执行sql文件 sql>@D:/lanxi_his_data/V_JH_VISITINFO.sql

  2. PostgreSQL 9.5,带来 UPSERT 等新特性

    PostgreSQL 9.5于2016年1月7日正式发布,此版本主要带来了以下几个方面的特性: UPSERT, Row Level Security, and Big Data 1)UPSERTUPS ...

  3. nodejs vue SyntaxError:Block-scoped declarations (let,const,function,class) not yet supported

    下午在git上导入之前写的代码到本地环境,执行npm run dev报错. 在我之前的环境中是没有问题的,这个错误信息也没看懂是什么原因引起的, 猜测可能是nodejs版本太低,于是重新下载了一个wi ...

  4. 畅通project(杭电1232)

    畅通project Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  5. [转]mysql 常用命令集锦[绝对精华]

    测试环境:mysql 5.0.45 [注:可以在mysql中通过mysql> SELECT VERSION();来查看数据库版本] 一.连接MYSQL. 格式: mysql -h主机地址 -u用 ...

  6. C#字符串来袭——因为爱,所以爱

    一直以来都喜欢谢霆锋,喜欢他身上的那股劲,也一直喜欢唱他的歌,比如这首最广为人知的<因为爱,所以爱>:因为爱所以爱,温柔经不起安排,愉快那么快,不要等到互相伤害...是的,没到互相伤害,他 ...

  7. VS报表图解《一》---菜鸟版

    与原先的开发环境VB.EXE不同VS2013自带了报表控件ReportViewer能够内部实现报表的设计,本文主要通过绑定数据集来实现报表的显示 1.加入:reportviewer控件,当将控件显示在 ...

  8. webDriver API——第11部分Remote WebDriver

    The WebDriver implementation. class selenium.webdriver.remote.webdriver.WebDriver(command_executor=' ...

  9. 第【一】部分Netzob项目工具的安装配置

    第[一]部分Netzob项目工具的安装配置 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途. 2)若本文档内有侵权文字或图片等内容,请联系作者bitp ...

  10. 使用js+Ajax请求API接口数据-带请求头方式

    C# http请求带请求头部分 先上代码: <script type="text/javascript"> function zLoginCheck() { var A ...