正题

loj 3026


题目大意

给你一棵树,和若干匹配串,如果一个节点向下的某条链构成了匹配串i,则可以花费这w_i匹配这条链,问你匹配完所有点的最小代价


解题思路

这题可以理解为树上树上的线性规划

先对于每个匹配串倒着建trie,然后每个点向父亲跑trie,当跑到一个匹配串时,就连接头和尾,费用为wiw_iwi​,流量inf

然后每个点向子节点连流量inf费用0的边

s向叶子节点连流量1费用0的边,如果一个点的子节点大于1就把多余的流到t,1要把所有流量流到t

就在树上找到匹配串,然后就是经典的线性规划


代码

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 510
#define M 1000100
using namespace std;
ll n, m, T, x, s, t, w, tot, ans, sum, summ;
ll h[N], f[N], b[N], fr[N], fa[N], deg[N], v[M], wh[M], to[M][26];
char cl[N], st[M];
bool p[N];
queue<ll>d;
const ll inf = 1e15;
struct rec
{ll to, next, f, w, c;
}e[N*N<<2];
void add(ll x, ll y, ll f, ll c, ll w)
{e[++tot].to = y;e[tot].f = f;e[tot].w = w;//编号e[tot].c = c;e[tot].next = h[x];h[x] = tot;e[++tot].to = x;e[tot].f = 0;e[tot].w = 0;e[tot].c = -c;e[tot].next = h[y];h[y] = tot;return;
}
void insert(ll x, char* s, ll whi)
{ll now = 0, len = strlen(s+1);for (ll i = len; i > 0; --i){ll y = s[i] - 97;if (!to[now][y]) to[now][y] = ++w;now = to[now][y];}if (!v[now] || x < v[now]){v[now] = x;wh[now] = whi;}return;
}
void dfs(ll x)
{ll now = 0;for (ll i = x; i != 1; i = fa[i]){ll y = cl[i] - 97;if (!to[now][y]) break;now = to[now][y];if (v[now]) add(x, fa[i], inf, v[now], wh[now]);}return;
}
bool spfa()
{memset(b, 127/3, sizeof(b));memset(f, 0, sizeof(f));memset(p, 0, sizeof(p));while(!d.empty()) d.pop();d.push(s);p[s] = 1;b[s] = 0;f[s] = inf;while(!d.empty()){ll u = d.front();d.pop();for (ll i = h[u]; i; i = e[i].next){ll v = e[i].to;if (b[u] + e[i].c < b[v] && e[i].f){fr[v] = i;b[v] = b[u] + e[i].c;f[v] = min(f[u], e[i].f);if (!p[v]){p[v] = 1;d.push(v);}}}p[u] = 0;}return f[t];
}
void dfs()
{ll now = t;while(fr[now]){e[fr[now]].f -= f[t];e[fr[now]^1].f += f[t];now = e[fr[now]^1].to;}ans += f[t] * b[t];sum += f[t];return;
}
int main()
{scanf("%lld%lld%lld", &n, &m, &T);tot = 1;for (ll i = 2; i <= n; ++i){scanf("%lld", &x);fa[i] = x;add(x, i, inf, 0, 0);deg[x]++; cl[i] = getchar();while(cl[i] < 'a' || 'z' < cl[i]) cl[i] = getchar();}s = n + 1;t = n + 2;for (ll i = 1; i <= m; ++i){scanf("%lld%s", &x, st+1);insert(x, st, i);}for (ll i = 2; i <= n; ++i){dfs(i);if (!deg[i]) add(s, i, 1, 0, 0);else if (deg[i] > 1){add(i, t, deg[i] - 1, 0, 0);//多的流掉summ += deg[i] - 1;//计算理论总流量}}add(1, t, deg[1], 0, 0);summ += deg[1];while(spfa())dfs();if (sum < summ)//有的边到不了{puts("-1");return 0;}printf("%lld\n", ans);if (T){ans = 0;for (ll i = 2; i <= n; ++i)for (ll j = h[i]; j; j = e[j].next)if (e[j].w && e[j].f < inf)//输出方案ans++;printf("%lld\n", ans);for (ll i = 2; i <= n; ++i)for (ll j = h[i]; j; j = e[j].next)if (e[j].w && e[j].f < inf)printf("%lld %lld %lld\n", e[j].to, i, e[j].w);}return 0;
}

【Trie】【费用流】管道监控(loj 3026)相关推荐

  1. Loj#3026-「ROIR 2018 Day1」管道监控【Trie,费用流】

    正题 题目链接:https://loj.ac/p/3026 题目大意 给出nnn个点的一棵外向树,然后mmm个字符串和费用表示你每次可以花费这个费用覆盖路径字符串和给出字符串相等的路径,求覆盖所有边的 ...

  2. Gym 101190D BZOJ 4842 Luogu P6967 LOJ #6071 [NEERC2016]Delight for a Cat (费用流)

    题目链接 (BZOJ) 大人,时代变了 (Gym) https://codeforces.com/gym/101190 (Luogu) https://www.luogu.com.cn/problem ...

  3. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

    题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...

  4. 【BZOJ2539】【codevs1221】丘比特的烦恼,trie树+几何判断+费用流

    传送门1 传送门2 写在前面:写90分不如写10分难 思路:很简单的思路!trie把字符串变成数字编号,邻接矩阵记录点之间的边权,判断是否在射程内或线段上是否有人不用什么斜率!用两点距离!然后直接上费 ...

  5. [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]

    题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...

  6. [费用流] LOJ#545. 「LibreOJ β Round #7」小埋与游乐场

    有两种操作是有效的 lowbit(ai)>lowbit(bj)lowbit(ai)>lowbit(bj)lowbit(a_i)>lowbit(b_j) 或者 ai=bjai=bja_ ...

  7. poj 3680 Intervals(离散化+费用流)

    题目链接:http://poj.org/problem?id=3680 题意: 给定n个带权开区间,选择其中一些区间出来,使得权值最大并且在任意被选区间的有效点上重叠层数不超过k. 解题思路: 这题可 ...

  8. [网络流24题] 航空路线问题 (费用流)

    洛谷传送门 LOJ传送门 这道题的图还挺好想的吧 反正都是无向边,起点走到终点再回到起点,就相当于从起点走$2$次到达终点,且这两次不经过相同的点,还要经过尽可能多的点 很经典的费用流建图 限制点通过 ...

  9. 网络流 最大流 最小割 费用流

    [腾讯文档]网络流初步 网络流初步 文章目录 网络流初步 一.网络流简介 1. 网络 2. 流 3. 再次理解网络流 二.常见题型(三种) 三.相关问题对应算法介绍 1.最大流 (1) FF算法 - ...

最新文章

  1. pdf格式转换成jpg的简单教程
  2. 使用ABAP编程实现对微软Office Word文档的操作
  3. LESSON 12.8 原理进阶 (1):GBDT数学流程与残差概念辨析
  4. matlab m n size a,matlab—size用法总结
  5. Busy Dialog init - hashchange will call BusyDialog.open - flower
  6. c语言表达式判断,在C语言的if语句中,用做判断的表达式为()。
  7. PHP 分布式集群中session共享问题以及session有效期的设置
  8. python pexpect pxssh scp_python Pexpect 实现输密码 scp 拷贝的方法
  9. vue 代理设置 访问图片_详解Vue源码之数据的代理访问
  10. while/for 嵌套expect 批量免密码传文件
  11. 动态球html,用html5标签让小球动起来
  12. URL different URI
  13. AX2012 R2安装
  14. 下载网页上的各种视频只需四步
  15. velocity模板使用手册
  16. 真正拖垮你的,是沉没成本
  17. 5个最佳团队交流应用程序
  18. cmd批处理的/d/l/r/f
  19. 常用数据指标缩写以及说明(uv、pv、br、cr、dau……):
  20. 云图说丨数字资产链:您的数字资产产权保护神

热门文章

  1. mysql必须的组件_mysql innodb的重要组件
  2. c语言格式字符If,C语言所有语句格式 C语言中的的if语句共有多少种格式?
  3. windows制作定时关机脚本_自动关机、自动打开程序… 让Windows自动执行任何操作...
  4. mysql 左连接 怎么走索引_数据库索引、左连接、右连接、等值连接
  5. 数据结构——最短路径之Dijkstra算法(与最小生成树的prime算法很像,建议一起看)
  6. C++ 学习之旅(16)——虚函数与纯虚函数virtual
  7. 每天一小时python官方文档学习(四)————数据结构之列表
  8. 基本程序单元Activity—Activity生命周期之数据传递小程序
  9. 蜘蛛牌 HDU - 1584(搜索——达到先让某些段先结合,达最优解)
  10. linux rsync删文件速度,Linux下使用rsync最快速删除大量文件的方法