CDOJ 1220 The Battle of Guandu
The Battle of Guandu
Time Limit: 6000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
In the year of 200, two generals whose names are Cao Cao and Shao Yuan are fighting in Guandu. The battle of Guandu was a great battle and the two armies were fighting at M different battlefields whose numbers were 1 to M. There were also N villages nearby numbered from 1 to N. Cao Cao could train some warriors from those villages to strengthen his military. For village i, Cao Cao could only call for some number of warriors join the battlefield xi. However, Shao Yuan's power was extremely strong at that time. So in order to protect themselves, village i would also send equal number of warriors to battlefield yi and join the Yuan Shao's Army. If Cao Cao had called for one warrior from village i, he would have to pay ci units of money for the village. There was no need for Cao Cao to pay for the warriors who would join Shao Yuan's army. At the beginning, there were no warriors of both sides in every battlefield.
As one of greatest strategist at that time, Cao Cao was considering how to beat Shao Yuan. As we can image, the battlefields would have different level of importance wi. Some of the battlefields with wi=2 were very important, so Cao Cao had to guarantee that in these battlefields, the number of his warriors was greater than Shao Yuan's. And some of the battlefields with wi=1 were not as important as before, so Cao Cao had to make sure that the number of his warriors was greater or equal to Shao Yuan's. The other battlefields with wi=0 had no importance, so there were no restriction about the number of warriors in those battlefields. Now, given such conditions, could you help Cao Cao find the least number of money he had to pay to win the battlefield?
Input
The first line of the input gives the number of test cases, T(1≤T≤30). T test cases follow.
Each test case begins with two integers N and M(1≤N,M≤105) in one line.
The second line contains N integers separated by blanks. The ith integer xi(1≤xi≤M) means Cao Cao could call for warriors from village i to battlefield xi.
The third line also contains N integers separated by blanks. The ith integer yi(1≤yi≤M) means if Cao Cao called some number of warriors from village i, there would be the same number of warriors join Shao Yuan's army and fight in battlefield yi.
The next line contains N integers separated by blanks. The ith integer ci(0≤ci≤105) means the number of money Cao Cao had to pay for each warrior from this village.
The last line contains M integers separated by blanks. The ith number wi(wi∈{0,1,2}) means the importance level of ith battlefield.
Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the least amount of money that Cao Cao had to pay for all the warriors to win the battle. If he couldn't win, y=−1.
Sample Input
2
2 3
2 3
1 1
1 1
0 1 2
1 1
1
1
1
2 Sample Output
Case #1: 1
Case #2: -1 解题:由于从i村庄给xi买人会导致yi战场上的敌人增加,由于胜负取决于人数,敌人增多,等同于yi战场的敌人数不变,caocao同学在yi战场上的人数减少。
所以可以这样子认为,我们从yi战场调来了人增援xi战场。但是,只能从不重要的0属性战场调来增援,因为这些战场胜负无关紧要,我们要保证能够胜利,所以以这些属性为0的战场为源点,求到必胜战场的最短路的和即可 下面是Q神的解释,非常清晰合理,完美啊
考虑每个战场的净人数(己方人数-对方人数),那么相当于第i个村庄花费c[i]的代价使得y[i]战场净人数-1,x[i]战场净人数+1,相当于转移了1个人过来。建立如下费用流模型,源向重要度为0的战场连容量INF费用0的弧,重要度为2的战场向汇连容量1费用0的弧,对于第i个村庄,战场y[i]向x[i]连容量INF费用c[i]的弧。如果满流,说明每个重要度为2的战场净人数>0,并且每个重要度为1的战场由于出入流平衡,净人数=0,于是能获胜。但是直接跑费用流是会TLE的,考虑每一次增广都是找一条从源到汇最短路,并且每次增广流量限制总为1,连向汇的费用总为0,因此可以从源出发跑一次单源最短路得到每次增广的费用,复杂度O((n+m)log(n+m))。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF = ~0ULL>>;
const int maxn = ;
int x[maxn],y[maxn],c[maxn],z[maxn];
struct arc{
int to,next;
LL w;
arc(int x = ,LL y = ,int z = -){
to = x;
w = y;
next = z;
}
}e[];
int head[maxn],tot;
LL d[maxn];
void add(int u,int v,LL w){
e[tot] = arc(v,w,head[u]);
head[u] = tot++;
}
queue<int>q;
bool in[maxn];
int main(){
int kase,N,M,cs = ;
scanf("%d",&kase);
while(kase--){
scanf("%d%d",&N,&M);
for(int i = ; i <= N; ++i)
scanf("%d",x + i);
for(int i = ; i <= N; ++i)
scanf("%d",y + i);
for(int i = ; i <= N; ++i)
scanf("%d",c + i);
for(int i = ; i <= M; ++i)
scanf("%d",z + i);
memset(head,-,sizeof head);
memset(in,false,sizeof in);
while(!q.empty()) q.pop();
tot = ;
for(int i = ; i <= N; ++i)
if(z[x[i]]) add(y[i],x[i],c[i]);
for(int i = ; i <= M; ++i){
if(!z[i]){
d[i] = ;
q.push(i);
in[i] = true;
}else d[i] = INF;
}
while(!q.empty()){
int u = q.front();
q.pop();
in[u] = false;
for(int i = head[u]; ~i; i = e[i].next){
if(d[e[i].to] > d[u] + e[i].w){
d[e[i].to] = d[u] + e[i].w;
if(!in[e[i].to]){
in[e[i].to] = true;
q.push(e[i].to);
}
}
}
}
LL ret = ;
bool flag = true;
for(int i = ; i <= M && flag; ++i){
if(z[i] == ){
if(d[i] == INF) flag = false;
else ret += d[i];
}
}
printf("Case #%d: %lld\n",cs++,flag?ret:-1LL);
}
return ;
}
CDOJ 1220 The Battle of Guandu的更多相关文章
- CDOJ UESTC 1220 The Battle of Guandu
The 2015 China Collegiate Programming Contest 2015第一届中国大学生程序设计竞赛 F题 本质就是求单源最短路!注意会爆int 对于每一个村庄i,其实就是 ...
- 2015南阳CCPC F - The Battle of Guandu 多源多汇最短路
The Battle of Guandu Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description In the year of 200, t ...
- CDOJ 1217 The Battle of Chibi
The Battle of Chibi Time Limit: 6000/4000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Othe ...
- cdoj 树上战争(Battle on the tree) Label:并查集?
给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxh和pfz初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜. Input 输入包含多组数据 每组第 ...
- hdu 5545 The Battle of Guandu spfa最短路
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5545 题意:有N个村庄, M 个战场: $ 1 <=N,M <= 10^5 $; 其中曹 ...
- CDOJ 889 Battle for Silver
Battle for Silver Time Limit: 2999/999MS (Java/Others) Memory Limit: 65432/65432KB (Java/Others) ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- Codeforces 738D. Sea Battle 模拟
D. Sea Battle time limit per test: 1 second memory limit per test :256 megabytes input: standard inp ...
- 1220 - Mysterious Bacteria--LightOj1220 (gcd)
http://lightoj.com/volume_showproblem.php?problem=1220 题目大意: 给你一个x,求出满足 x=b^p, p最大是几. 分析:x=p1^a1*p2^ ...
随机推荐
- 求n的因子个数与其因子数之和
方法一:朴素算法:O(n). #include<bits/stdc++.h> using namespace std; int get_num(int n){ ; ;i<=n;++i ...
- Hash环/一致性Hash原理
当前,Memcached.Redis这类分布式kv缓存已经非常普遍.从本篇开始,本系列将分析分布式缓存相关的原理.使用策略和最佳实践. 我们知道Memcached的分布式其实是一种“伪分布式”,也就是 ...
- 【前端】jQurey Plugin
; (function ($, window, document, undefined) { "use strict"; var defaults = { name: " ...
- 享元模式及php实现
享元模式: 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用.由于享元模式要求 ...
- javascript中 if(变量)和if(变量==true)的区别
if(判断表达式){执行内容} 如果判断表达式为true,则执行括号中的内容.这里,变量如果不为0,null,undefined,false,都会被处理为true.只要变量有非0的值或是某个对象,数组 ...
- Android掌中游斗地主游戏源码完整版
源码大放送-掌中游斗地主(完整版),集合了单机斗地主.网络斗地主.癞子斗地主等,有史以来最有参考价值的源码,虽然运行慢了一点但是功能正常,用的是纯java写的. 项目详细说明:http://andro ...
- 微信小程序开发系列二:微信小程序的视图设计
大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...
- (转)关于treap的板子理解
关于treap的板子理解: 关于结构体的定义:(一般平衡树无法理解的变量名):v:节点的值:size:子节点的个数(包括自己):cnt:相同的值的副本数:l:左儿子:r:右儿子: 右旋:父亲变成左儿子 ...
- 检查bug
用selective_search生成的坐标是(ymin,xmin,ymax,xmax),并且是从1开始的,不是从0 这是cache中的gt数据,明显看到有65535,说明很有可能是0-1变成了655 ...
- 【转】Delphi 2010 Lite加装帮助文件
基于爱好,下载了一个delphi 2010 lite,业余玩玩. 不过这东西是网友重新打包的,没有带帮助.在网上搜索一下加摸索后搞定.步骤如下: Delphi 2010本身的帮助(MSDN风格的)1. ...