手抄代码 + 学习指针 + 冥思苦想一晚上终于——在一瞬间开窍了。果然题目都是这样:突破了一个点,一切都是柳暗花明。

  题面描述:

  样例:

  这道题目,首先注意到给定的边的性质:这些边在平面上构成了一棵树,区间之间互不相交,只有包含与外离两种关系。如果不考虑颜色的限制,我们将原图的边权转化为网络流中的流量,那么原图中的最短路就转化为了新图中的最小割。那么在张网络流的图上,我们应当如何限制颜色的制约关系呢?

  首先一个明显的思路:这张图是一个树形的结构,画在一个类似数轴的东西上面会很容易发现最下面的一条链上的点是无论如何都要经过的;而不存在于这条链上的点,则一定不会被访问到,其所代表的颜色也一定不会被我们所选择。对于这样的点,我们将它们从我们的图上删去。最小割:将图中的点分做S割与T割的两个部分。我们对于每一个颜色都做出一个辅助点,若这个点位于S割,代表这个颜色被选择;位于T割,代表不被选择。

  我们将所有的边画成树后,从所有的大区间层层推进的向其所包含的小区间连边(类似线段树)。注意在这里我们先忽略那些链接相邻两点的区间不作处理。一个显然的性质:一个大区间所跳过的点,一定包含了所有它包含的小区间跳过的点。那么我们就从区间往它跳过的颜色的点连上INF的边(如果大区间&小区间共同跳过了一个颜色,这条边从小区间->颜色)。注意之前我们确定一定不会经过的颜色,从它向T点连INF的边,保证它一定处于T割。

  这样我们可以发现:如果不选择这一个点,说明我们的割线一定在这个颜色的点的上方->我们选择了所有跳过这个颜色的区间。如果选择一个点,说明我们的割线在这个点的下方->我们没有选择任何一个跳过这个颜色的区间。这样,限制就得以满足了。最后,那些链接相邻两点的边:如果包含于大区间,则由这些区间其中最小的一个向T点连边权值的流量的边,否则就从S连向T,流量也为边权值。

  感觉读懂了之后除了感叹还是感叹——我学过网络流吗?不存在的。【摊手】

#include <bits/stdc++.h>
using namespace std;
#define maxn 10000
#define INF 99999
#define pb push_back
#define vec vector
int n, m, cnp, cnt, s, t;
int Map[maxn][maxn], lev[maxn], nxt[maxn];
int ans, a[maxn], id[maxn];
bool tag[maxn], mark[maxn], flag[maxn];
vector <int> u, v, w, c;
queue <int> q; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct node
{
int u, v, w; bool flag;
bool operator <(node t)
{ return v - u < t.v - t.u; } // 区间长度短的放在前面
}E[maxn]; struct edge
{
int v, f;
edge *nxt, *rev;
}e[], *p = e, *head[maxn], *cur[maxn]; void add(int u, int v, int f1, int f2)
{
*p = (edge) { v, f1, head[u], p + }, head[u] = p ++;
*p = (edge) { u, f2, head[v], p - }, head[v] = p ++;
} bool bfs()
{
memset(lev, , sizeof(lev));
q.push(s); lev[s] = ;
while(!q.empty())
{
int u = q.front(); q.pop();
for(edge *i = head[u]; i; i = i -> nxt)
{
if(!lev[i -> v] && i -> f)
{
lev[i -> v] = lev[u] + ;
q.push(i -> v);
}
}
}
return lev[t];
} int dfs(int x, int nf)
{
int ff = ;
if(x == t) return nf;
for(edge *i = cur[x]; i; i = i -> nxt)
{
if(!nf) break;
if(i -> f && lev[i -> v] == lev[x] + )
{
int af = dfs(i -> v, min(nf, i -> f));
i -> f -= af, i -> rev -> f += af, cur[x] = i;
ff += af, nf -= af;
}
}
cur[x] = head[x];
return ff;
} int Work(vec <int> u, vec <int> v, vec <int> w, vec <int> c)
{
memset(Map, , sizeof(Map));
for(int i = ; i < (int) u.size(); i ++)
Map[u[i]][v[i]] = Map[v[i]][u[i]] = min(Map[u[i]][v[i]], w[i]);
flag[n] = ;
for(int i = n - ; i; i --)
for(int j = i + ; j <= n; j ++)
flag[i] |= flag[j] && Map[i][j] < << ;
for(int i = ; i <= n; i = nxt[i])
{
a[id[i] = ++ cnt] = i; nxt[i] = n + ;
for(int j = i + ; j <= n; j ++)
if(Map[i][j] < << && nxt[i] > n && flag[j])
{ nxt[i] = j; break; }
for(int j = ; j < i; j ++)
if(Map[i][j] < << && id[j] && id[j] != cnt - )
E[++ cnp] = (node) { id[j], cnt, Map[i][j], };
}
if(a[cnt] != n) return -;
E[++ cnp] = (node) { id[], id[n], , };
sort(E + , E + cnp);
s = cnp, t = cnp + ;
for(int i = ; i <= n - ; i ++)
if(!id[i]) add(cnp + c[i - ], t, << , << );
for(int i = ; i <= cnp; i ++)
{
for(int j = ; j < i; j ++)
if(!E[j].flag && E[i].u <= E[j].u && E[i].v >= E[j].v)
E[j].flag = , add(i, j, E[j].w, << );
for(int j = E[i].u + ; j < E[i].v; j ++)
if(!tag[j]) tag[j] = , add(i, cnp + c[a[j] - ], << , << );
for(int j = E[i].u; j < E[i].v; j ++)
if(!mark[j]) mark[j] = , add(i, t, Map[a[j]][a[j + ]], );
}
for(int i = ; i <= t; i ++) cur[i] = head[i];
while(bfs()) if((ans += dfs(s, << )) >= INF) return -;
return ans;
} int main()
{
n = read(), m = read();
for(int i = ; i <= n - ; i ++)
{
int x = read();
c.pb(x);
}
for(int i = ; i <= m; i ++)
{
int x = read(), y = read(), z = read();
u.pb(x), v.pb(y), w.pb(z);
}
printf("%d\n", Work(u, v, w, c));
return ;
}

【考试记录】4.8 Path (网络流 —— 劲题)的更多相关文章

  1. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  2. 【网络流24题】最长k可重区间集(费用流)

    [网络流24题]最长k可重区间集(费用流) 题面 Cogs Loj 洛谷 题解 首先注意一下 这道题目里面 在Cogs上直接做就行了 洛谷和Loj上需要判断数据合法,如果\(l>r\)就要交换\ ...

  3. LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集

    #6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   ...

  4. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  5. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  6. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

  7. LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

    #6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  8. LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流

    #6011. 「网络流 24 题」运输问题 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  9. LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图

    #6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

随机推荐

  1. 一张表搞清楚 php 的 is_null、empty、isset的区别

    isset 判断变量是否已存在 empty 判断变量是否为空或为0 is_null 判断变量是否为NULL 变量 empty is_null isset $a=”” true false true $ ...

  2. C语言实例解析精粹学习笔记——34(用“结构”统计学生成绩)

    实例34: 设学生信息包括学号.姓名和五门功课的成绩,要求编写输入输出学生信息的函数.在输入学生信息后,以学生成绩的总分从高到低顺序输出学生信息. 思路: 程序引入一个结构数组依次存储输入的学生信息, ...

  3. $.ajax()各方法详解(转)

    jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...

  4. 1321. [ZJOI2012] 灾难

    1321. [ZJOI2012] 灾难 ★★☆   输入文件:catas.in   输出文件:catas.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 阿米巴是小强的 ...

  5. AWS安装CDH5.3-CentOS6.4中关键操作步骤

    1.在AWS masternode 上下载cloudera-manager-installer.bin安装包 [root@ip-172-21-42-114 ~]# wget http://archiv ...

  6. Python操作nosql数据库之redis

    一.NoSQL的操作 NoSQL,泛指非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不 ...

  7. Java开发WebService(使用Java-WS)

    前言: 初学Java,因为工作需要,直接跳到开发WebService.以前用.NET开发过WebService,对比一下,Java的WebService开发部署难度高了不止一个档次.网上的教程各式各异 ...

  8. 3.Linux 文件的压缩与打包

    1.常用压缩打包命令 常用的压缩打包扩展名为如下: *.Z compress 程序压缩的文件,非常老旧了,不再细说 *.gz gzip 程序压缩的文件: *.bz2 bzip2 程序压缩的文件: *. ...

  9. 【功能笔记】Ubuntu查看系统资源占用(内存,cpu和进程) {转载}

    转载自http://bluexp29.blog.163.com/blog/static/33858148201071534450856/ linux真是太强大了. 查看ubuntu的资源占用的命令为$ ...

  10. 【转】Linux学习(1)-常用快捷键、文件管理和查询

    原文链接:http://www.cnblogs.com/zhaopei/p/7397402.html 有话要说 为什么要用Linux?要用Linux的原因太多,想说说不完啊. 如果你说用Linux只是 ...