[JZOJ1900] 【2010集训队出题】矩阵
题目
题目大意
题目化简一下,就变成:
构造一个\(01\)数列\(A\),使得\(D=\sum A_iA_jB_{i,j}-\sum A_iC_i\)最大。
问这个最大的\(D\)是多少。
正解
其实这是一个网络流的二元关系问题……
如果\(A_i\)为\(1\),则会有\(-C_i\)的贡献。
如果\(A_i\)和\(A_j\)皆为\(1\),则会有\(B_{i,j}\)的贡献。
然后很显然地,\(70\)分的方法就出来了:每个点朝汇点连一条容量为\(C_i\)的边,对于每个\(B_{i,j}\),建一个新点,从源点朝它连一条容量为\(B_{i,j}\)的边,它朝\(i\)和\(j\)连容量为无限大的边。然后最小割即可。
这个算法的瓶颈在于这些新点太多了,能不能不用建立新点?
实际上有个很妙的方法:对于每一对\(i\)和\(j\),从原点向\(i\)连一条容量为\(B_{i,j}\)的边,同样地向\(j\)连一条容量为\(B_{j,i}\)的边。\(i\)向\(j\)连一条容量为\(B_{i,j}\)的边,\(j\)向\(i\)连一条容量为\(B_{j,i}\)的边。
那么这有什么用呢?当\(C_i\)的那条边被保留的时候,源点向\(i\)连的那条\(B_{i,j}\)的边会被割掉,还有源点连向\(j\)或者\(j\)连向\(i\)的那条边也会被割掉。
另一种建图方式跟这个比较类似,只是把边权换成了\(\frac{B_{i,j}+B_{j,i}}{2}\)罢了。因为只要保留\(C_i\)或者\(C_j\),割掉的边都是\(B_{i,j}+B_{j,i}\)。
对于源点向\(i\)和\(j\)连的边,显然可以合并起来。所以图中的点和边的数量就大大减少了。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#define N 610
inline int input(){
char ch=getchar();
while (ch<'0' || '9'<ch)
ch=getchar();
int x=0;
do{
x=x*10+ch-'0';
ch=getchar();
}
while ('0'<=ch && ch<='9');
return x;
}
int n;
int b[N][N],c[N];
struct EDGE{
int to,c;
EDGE *las;
} e[2000000];
int ne;
EDGE *last[N];
inline void link(int u,int v,int c){
e[ne]={v,c,last[u]};
last[u]=e+ne++;
}
int S,T;
#define rev(ei) (e+(((ei)-e)^1))
int dis[N],gap[N],BZ;
EDGE *cur[N];
int dfs(int x,int s){
if (x==T)
return s;
int have=0;
for (EDGE *ei=cur[x];ei;ei=ei->las){
cur[x]=ei;
if (ei->c && dis[x]==dis[ei->to]+1){
int t=dfs(ei->to,min(s-have,ei->c));
ei->c-=t,rev(ei)->c+=t,have+=t;
if (have==s)
return s;
}
}
cur[x]=last[x];
if (!--gap[dis[x]])
BZ=0;
dis[x]++;
gap[dis[x]]++;
return have;
}
inline int flow(){
gap[0]=n+2;
int res=0;
BZ=1;
while (BZ)
res+=dfs(S,INT_MAX);
return res;
}
int main(){
n=input();
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
b[i][j]=input();
for (int i=1;i<=n;++i)
c[i]=input();
S=n+1,T=n+2;
int all=0;
for (int i=1;i<=n;++i){
int sum=0;
for (int j=1;j<=n;++j)
sum+=b[j][i];
all+=sum;
link(S,i,sum),link(i,S,0);
for (int j=1;j<i;++j)
link(i,j,b[j][i]),link(j,i,b[i][j]);
link(i,T,c[i]),link(T,i,0);
}
printf("%d\n",all-flow());
return 0;
}
总结
见到二元关系类型的题目,首先要想到网络流啊……
[JZOJ1900] 【2010集训队出题】矩阵的更多相关文章
- [JZOJ1901] 【2010集训队出题】光棱坦克
题目 题目大意 给你个平面上的一堆点,问序列\({p_i}\)的个数. 满足\(y_{p_{i-1}}>y_{p_i}\)并且\(x_{p_i}\)在\(x_{p_i-1}\)和\(x_{p_i ...
- [JZOJ1904] 【2010集训队出题】拯救Protoss的故乡
题目 题目大意 给你一个树形的网络,每条边从父亲流向儿子.根节点为原点,叶子节点流向汇点,容量为无穷大. 可以给一些边扩大容量,最多总共扩大\(m\)容量.每条边的容量有上限. 求扩大容量后最大的最大 ...
- [期望DP][纪中]【2010集训队出题】彩色圆环
彩色圆环 感谢名单 十分感谢 JA_Ma 为我讲解了 \(T1\) 的 期望DP 的思想和推论. 十分感谢 SSL_LYF 为我解答了 \(T1\) 的 期望DP 的概率的大小问题. 十分感谢 SSL ...
- 2019.01.02 bzoj2467: [中山市选2010]生成树(矩阵树定理)
传送门 矩阵树定理模板题. 题意简述:自己看题面吧太简单懒得写了 直接构建出这4n4n4n个点然后按照题面连边之后跑矩阵树即可. 代码: #include<bits/stdc++.h> # ...
- BZOJ 2467: [中山市选2010]生成树(矩阵树定理+取模高斯消元)
http://www.lydsy.com/JudgeOnline/problem.php?id=2467 题意: 思路:要用矩阵树定理不难,但是这里的话需要取模,所以是需要计算逆元的,但是用辗转相减会 ...
- bzoj 2252 [ 2010 Beijing wc ] 矩阵距离 —— 多源bfs
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2252 又没能自己想出来... 一直在想如何从每个1开始广搜更新答案,再剪剪枝,什么遇到1就不 ...
- 数据结构(莫队算法):国家集训队2010 小Z的袜子
[题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到 ...
- 【国家集训队2010】小Z的袜子[莫队算法]
[莫队算法][国家集训队2010]小Z的袜子 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程, ...
- 【BZOJ2117】 [2010国家集训队]Crash的旅游计划
[BZOJ2117] [2010国家集训队]Crash的旅游计划 Description 眼看着假期就要到了,Crash由于长期切题而感到无聊了,因此他决定利用这个假期和好友陶陶一起出去旅游. Cra ...
随机推荐
- Front Page
General Team FST stay night from ShanDong University 19 - 20 CCPC QinHuangDao Gold (4 th) IUPC YinCh ...
- Codeforces Round #535 F-MST Unification
题目大意: 给定n m 为图中的点数n和边数m 给定m条边的信息 u v w 为u点到v点有一条长度为w的边 图中无环无重边 这个图的MST的花费为k 但可能存在多种花费为k的MST的方案 此时对图中 ...
- 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)
题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...
- Android四大组件之Service浅见
Service 是Android四大组件之一,可以在不显示界面的情况下在后台运行.还有一个作用是通过AIDL来实现进程间通信. Service的启动方式 Service的启动方式有两种,startSe ...
- 22-1-sort
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于EntityFramework 更新数据记录时字段全部更新问题和不从数据库中获取直接更新记录
一.一直对这个比较疑惑感觉只修改一条数据记录的一个字段结果更新Savechages后跟踪生成sql竟然是全部被修改,感觉微软怎么这么傻,总觉得会有其它方式可以只更新部分字段,但一直没有找到相关设置,最 ...
- 使用wireshark在windows平台下捕获HTTP协议数据包中的帐号密码信息
1.打开wireshark软件,从Interface List中选择相应的网卡,例如我的PC机上是“本地连接”,然后选择”Start”启动抓包程序. 2.打开学校主页,输入账号和密码登录校内邮箱. 3 ...
- 面对对象(JS)
面对对象的三大特征:封闭.继承.多态 七大基本原则: 1.单一职责 2.开闭原则 3.里氏替换 4.依赖倒置 5.接口隔离 6.迪米特法则 7.01组合/聚合 ...
- Grafana + Influxdb Android性能监控部署
目录 前言 一.前提准备 二.安装 Grafana 三.安装 Influxdb 四.Grafana 添加 Influxdb 数据源 五.Shell 脚本写入数据到 Influxdb 前言 你是否为了数 ...
- JavaWeb学习篇之----Tomcat中配置数字证书以及网络传输数据中的密码学知识
今天是学习JavaWeb的第二天,我们来了解什么呢?就了解一下Tomcat中配置数字证书的相关内容,但是在说这部分内容的时候,我们貌似得先说一下数字证书的相关概念,那说到数字证书的时候我们还得了解一些 ...