CF_884_F(NetFlow)
题目大意:给出一串长为n
的字符串(保证n
为偶数),定义反回文串为每一个位置的对应位置上的字母都不等于它(for each i : s[i] != s[n+1-i]
),现可将原字符串随意排列,得到一个反回文串(保证有解),若最后的反回文串(设为s'
)上的某一位置i
有s[i] == s'[i]
,则可以得到一个美丽值b[i]
,求将原串变为反回文串所可以得到的最大美丽值和(sum_b[i]
,s[i] == s'[i]
)。
题解:直接求最大美丽值有困难,可以反着想,我们通过改动某些位置让原串变为反回文串,若可以求出最小花费之和(对应位置的美丽值),用总的美丽值之和扣除最小花费便是答案。打的时候由于E题加粗内存限制,题面都没看就来了F,发现F是费用流还有点开心,结果画了好久都没有画出来建图,最后看了题解好一会才想通建图方式。
建图解释:首先这题的图有5层,1(S)->2( 26 letters )->3( 26 * n/2 nodes )->4( n poisions )->T
,其实最关键的就是第三层,因为其他层都是正常操作,基本上都会这样建图,关键就是第三层的26*n/2
个点是用来做什么的?接下来给出解释:首先,我们目标是用最小费用最大流跑出最小花费(即达到最大流量的最小花费)。那么显然(2->5
)这些层的容量都是1
,因为每个字母对于每个位置,以及每个位置对于整串只能贡献1
流量,然后(1->2
)的边容量为每个字母在s
串中出现的次数,也很好理解,就是最多能用几次,而费用我们选择在第三四层计算,所以剩下的费用都是0。
关键来了,第三层是什么东西,第三层可以这样理解,对于某一个字母(称作cur
),显然cur
如果在第一个位置,就不能在最后一个位置(因为要反回文),所以我们将cur
在第三层中的第一个点和第一个和最后一个位置(第4层)建边(f=1,w=?
),先考虑为何不拿将cur
分出n
个在第三层的点,分别与对应位置建边?因为反回文,如果第1
条和第n
条的花费是这n
条中最小的两个,那么都会被采用,那么第一个位置和最后一个位置都是同一个字母,就违反了反回文的性质,所以只拆出n/2
个点,那么费用是多少?回顾一下我们要做的事情,是构造出一个反回文,而如果流量从cur
第一个属于第三层的点流到第一个位置,说明cur
填在第一个位置,那么如果原来第一个位置就是cur
显然可以得到b[1]
,那么因为我们最后是用总美丽值减去我们跑出来的最小费用,所以这条边的费用为0
,这样被扣掉就拿到了b[1]
,反之如果原来第一个位置不是cur
,这条边的费用就是b[1]
,这样被扣掉就拿不到了,对于其他位置以此类推(某个点第三层的第2个点,连向第四层中n
个位置的第2个位置和倒数第2个位置,即每个字母在第三层中的n/2
个点,分别对应第一倒一,第二倒二,第三倒三……)。
PS:依旧是Dij + g[]
,我的g
就是势数组。
#pragma comment(linkerr, "/STACK: 1024000000,1024000000")
#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define em emplace
#define pii pair<int,int>
#define de(x) cout << #x << " = " << x << endl
#define clr(a,b) memset(a,b,sizeof(a))
#define INF (0x3f3f3f3f)
#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))
#define F first
#define S second
using namespace std;
const int N = 110;
int n, S, T;
int ct[27], b[N];
char s[N];
struct Edge
{
int v, nxt;
int f, w;
};
Edge e[N*N<<2];
int h[N*N], ect;
int dis[N*N], g[N*N], pv[N*N], pe[N*N];
bool vis[N*N];
void init()
{
clr(h,-1);
ect = 0;
}
void _add( int u, int v, int f, int w )
{
e[ect].v = v; e[ect].f = f; e[ect].w = w; e[ect].nxt = h[u]; h[u] = ect++;
e[ect].v = u; e[ect].f = 0; e[ect].w =-w; e[ect].nxt = h[v]; h[v] = ect++;
}
pii mfmc( int s, int t )
{
int mxf = 0, mnc = 0;
while ( 1 )
{
clr(vis,0); clr(dis,INF);
dis[s] = 0;
priority_queue<pii> q;
q.push( {0,s} );
while ( !q.empty() )
{
pii nw = q.top(); q.pop();
int u = nw.S;
if ( vis[u] ) continue;
vis[u] = 1;
for ( int i = h[u], v = e[i].v; i+1; i = e[i].nxt, v = e[i].v )
{
int c = e[i].w + g[u] - g[v];
if ( e[i].f > 0 && dis[v] > dis[u] + c )
{
dis[v] = dis[u] + c;
q.push( {-dis[v],v} );
pv[v] = u; pe[v] = i;
}
}
}
if ( dis[t] == INF ) break;
for ( int i = s; i <= t; i ++ )
g[i] += dis[i];
int d = INF;
for ( int i = t; i != s; i = pv[i] )
d = min( d, e[pe[i]].f );
for ( int i = t; i != s; i = pv[i] )
e[pe[i]].f -= d, e[pe[i]^1].f += d;
mxf += d; mnc += d*g[t];
}
return {mxf, mnc};
}
int main()
{
init();
int sm = 0;
scanf("%d", &n);
scanf("%s", s+1);
for ( int i = 1; i <= n; i ++ )
ct[s[i]-'a'+1] ++;
for ( int i = 1; i <= n; i ++ )
scanf("%d", &b[i]), sm += b[i];
S = 0, T = 26 + 26*n/2 + n + 1;
for ( int i = 1; i < 27; i ++ )
_add( S, i, ct[i], 0 );
int nw, tp;
nw = 26;
for ( int i = 1; i < 27; i ++ )
for ( int j = 1; j+j <= n; j ++ )
_add( i, ++nw, 1, 0 );
nw = 26 + 26*n/2, tp = 26;
for ( int i = 0; i < 26; i ++ )
for ( int j = 1; j+j <= n; j ++ )
_add( ++tp, nw + j, 1, s[j] - 'a' == i ? 0 : b[j] ),
_add( tp, nw + n + 1 - j, 1, s[n+1-j] - 'a' == i ? 0 : b[n+1-j] );
nw = T - 1;
for ( int i = 0; i < n; i ++ )
_add( nw, T, 1, 0 ), nw --;
pii cur = mfmc( S, T );
printf("%d\n", sm - cur.S);
return 0;
}
CF_884_F(NetFlow)的更多相关文章
- GitHub NetFlow
https://github.com/search?l=Java&p=1&q=netflow&ref=searchresults&type=Repositories&a ...
- NetFlow
供应商 支持的流 设备列表 Cisco NetFlow Cisco - 800.1700.2600.1800.2800.3800.4500.6500.7200.7300.7500.7600.10000 ...
- 【流量】netflow 基础知识
摘要 记录下关于netflow的基础知识以及应用,现状 是什么 一种数据交换方式,NetFlow流量统计数据包括数据流时戳 源IP地址和目的IP地址 源端口号和目的端口号 输入接口号和输出接口号 下一 ...
- NetFlow学习笔记
NetFlow学习笔记 标签: netflow 由于工作需要,对NetFlow做了一些学习和调研,并总结成文档以供学习分享. 背景:随着系统的升级与漏洞的修补,入侵主机进而进行破坏的病毒攻击方式在攻击 ...
- 基于Spark和SparkSQL的NetFlow流量的初步分析——scala语言
基于Spark和SparkSQL的NetFlow流量的初步分析--scala语言 标签: NetFlow Spark SparkSQL 本文主要是介绍如何使用Spark做一些简单的NetFlow数据的 ...
- Openvswitch手册(3): sFlow, netFlow
这一节,我们重点看sFlow 采样流sFlow(Sampled Flow)是一种基于报文采样的网络流量监控技术,主要用于对网络流量进行统计分析. sFlow系统包含一个嵌入在设备中的sFlow Age ...
- [转]Comparing sFlow and NetFlow in a vSwitch
As virtualization shifts the network edge from top of rack switches to software virtual switches run ...
- [转]Rapidly detecting large flows, sFlow vs. NetFlow/IPFIX
Figure 1: Low latency software defined networking control loop The articles SDN and delay and Delay ...
- Cisco ISR4400 Netflow 配置模板
flow exporter NAME destination 145.0.1.200 transport udp 9991 export-protocol netflow-v5 flow monito ...
随机推荐
- kubernetes 创建tomcat 容器
方案一: 使用k8s dashboard 创建rc 1. 界面操作 提示:暂时 忽略 查看: 2.测试 由于是外部服务 直接用 节点的ip访问: 同样也是 第二个端口可以访问.感觉 跟之前的提 ...
- python的类继承与派生
一.继承和派生简介: 其实是一个一个事物站在不同角度去看,说白了就是基于一个或几个类定义一个新的类.比如定义了动物类接着派生出了人类,你也可以说人类继承了动物类.一个意思.此外python类似于C和C ...
- Python - 3.6 学习四
错误.调试和测试 程序运行中,可能会遇到BUG.用户输入异常数据以及其它环境的异常,这些都需要程序猿进行处理.Python提供了一套内置的异常处理机制,供程序猿使用,同时PDB提供了调试代码的功能,除 ...
- Linux操作系统上ADSL拨号上网的方法详解
1.安装 yum install rp-pppoe.x86_64 2.配置PPPOE客户端软件 安装完软件包后,必须配置pppoe的配置文件/etc/ppp/pppoe.conf,从而让ADSL拨号时 ...
- 安装 sql server 2008出现重启电脑,另在server 2012 r2安装sql server 2008 安装不上
时即使是进行电脑重启,也会报这个错误,那么就不是电脑的问题了,其实是系统注册表在作怪,解决方法如下: 1.开始-->运行,输入regedit,打开注册表管理器: 2. 找到 HKEY_LOCAL ...
- vue 缓存的keepalive页面刷新数据
用到这个的业务场景是这样的: a页面点击新建列表按钮进入到新建的页面b,填写b页面并点击b页面确认添加按钮,把这些数据带到a页面,填充到列表(数组),可以添加多条, 点击这条的时候进入到编辑页面,确认 ...
- Dreamweaver 中CSS代码格式化
首先,用DW打开一个已经写好的css文件,看一下编辑好的,没有格式化之前的代码的样子. 然后,我们点击软件窗口上方的“命令”选项,在弹出的菜单中点击“应用源格式”选项,就可以将我们的代码格式化. ...
- sort命令详解及Nginx统计运用
sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式: sort [-bcfMnrtk][源文件][-o 输出文件] 补充说明:sort可针对文本文件的内容,以行为单位来排序. 参 数 ...
- 160227、javascript特效
1.给网页设定快捷键 js: function getkey(){ event = event || window.event; url = "www.baidu.com&q ...
- poj3764 The XOR Longest Path【dfs】【Trie树】
The xor-longest Path Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10038 Accepted: ...