codeforces863F Almost Permutation 费用流
题意:
构造出一个数列,数字在$1~n$的范围内,要求$\sum_{i=1}^n count(i)^{2}$最小,$count(i)$的意思是数列中i出现的次数。并且数列要满足两种类型的条件,一个是$a_i->a_j$全部大于v,还有$a_i->a_j$全部小于v。
思路:
首先,我们可以把限制条件转化为某个位置上数值的上限和下限,然后位置和对应能填的所有数字都建容量为1的边,然后每一个数字向汇点建n条容量为1的边,费用分别是$1,3,5,……,2*j-1$,这样建边后,如果一个数字被选取了两次,得到的前缀和刚好就是出现次数的平方。
#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
const int maxn=;
const int inf=0x3f3f3f3f;
ll rd()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, next, cap, flow, cost; } edge[MAXM];
struct pp{
int u,v,c,w;
}in[MAXN];
int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N=MAXN-;
int n,q,l[MAXN],r[MAXN];
void init() { tol = ;
memset(head, -, sizeof(head)); }
void addv(int u, int v, int cap, int cost) {
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = ;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = ;
edge[tol].cost = -cost;
edge[tol].flow = ;
edge[tol].next = head[v];
head[v] = tol++; }
bool spfa(int s, int t) {
queue<int>q;
clr(dis,INF);
clr(vis,),clr(pre,-); dis[s] = ;
vis[s] = true;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]) {
vis[v] = true;
q.push(v); } } } }
if (pre[t] == -)return false;
else return true; }
//返回的是最大流,cost 存的是最小费用
int minCostMaxflow(int s, int t, int &cost) {
int flow = ;
cost = ;
while (spfa(s, t)) {
int Min = INF;
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]) {
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow; }
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]) {
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
cost += edge[i].cost * Min; }
flow += Min; }
return flow; }
int main(){
cin>>n>>q;
init();
int S=,T=*n+;
rep(i,,n){
addv(S,i,,);
r[i]=n;
l[i]=;
rep(j,,n){
addv(i+n,T,,*j-);
}
}
int flag=;
while(q--){
int op,x,y,v;
scanf("%d%d%d%d",&op,&x,&y,&v);
if(op==){
rep(i,x,y){
l[i]=max(l[i],v);
}
}else{
rep(i,x,y){
r[i]=min(r[i],v);
}
}
}
rep(i,,n){
if(l[i]>r[i]){
flag=;
break;
}
rep(j,l[i],r[i]){
addv(i,j+n,,);
}
}
if(flag==){
puts("-1");
return ;
}
int c;
minCostMaxflow(S,T,c);
cout<<c<<endl; }
codeforces863F Almost Permutation 费用流的更多相关文章
- hdu-5988 Coding Contest(费用流)
题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 5 ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
- Codeforces 730I [费用流]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...
- zkw费用流+当前弧优化
zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...
- 【BZOJ-4213】贪吃蛇 有上下界的费用流
4213: 贪吃蛇 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 58 Solved: 24[Submit][Status][Discuss] Desc ...
- 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广
3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 174 Solved: 9 ...
- [bzoj4514]数字配对[费用流]
今年SDOI的题,看到他们在做,看到过了一百多个人,然后就被虐惨啦... 果然考试的时候还是打不了高端算法,调了...几天 默默地yy了一个费用流构图: 源连所有点,配对的点连啊,所有点连汇... 后 ...
随机推荐
- 力扣 — Rotate List()
题目描述: 中文: 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = ...
- 使用 jQuery 实现当前页面高亮显示的通栏导航条
index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...
- 17.Priority优先级
/** * 优先级 */ public class PriorityDemo { public static class HightPriority extends Thread{ static in ...
- iSkysoft iMedia Converter Deluxe for Mac的使用方法
我们电脑上的播放器大多数的播放格式都比较少,所以在播放其它格式的时候容易出错,不能兼容其它的视频格式.今天小编要给大家推荐一种软件,iSkysoft iMedia Converter Deluxe就是 ...
- paper 138:qt安装及问题解决
学习了很久的QT,遇到很多很多的问题,下面总结一下安装过程中遇到的问题吧, 1 下载QT 1)进入官网:https://www.qt.io/ 2)点击Download:https://www.qt.i ...
- Python(二)
函数Python的函数支持递归.默认参数值.可变参数,但不支持函数重载.为了增强代码的可读性,可以在函数后书写“文档字符串”(Documentation Strings,或者简称docstrings) ...
- [CSP-S模拟测试]:工业题/a(数学)
题目传送门(内部题39) 输入格式 第一行:四个正整数$n$.$m$.$a$.$b$.第二行:$n$个正整数,第$i$个表示$f(i,0)$.第三行:$m$个正整数,第$i$个表示$f(0,i)$. ...
- Linux桌面与命令行切换
1.首先在安装Linux的时候是选则Desktop桌面方式安装 2.切换命令 2.1快捷键:Ctrl+Alt+F1 切换到桌面模式 Ctrl+Alt+F3 切换到命令行模式
- Postgresql物理存储结构
Postgresql目前不支持使用裸设备和块设备. Postgresql的属于 Relation:表示表或索引. Tuple:表示表中的行. Page:表示在磁盘中的数据块. Buffer:表示在内存 ...
- 利用core_pattern实现core文件的配置和管理
参考:https://xz.aliyun.com/t/1098 这里所说的core_pattern 指的是:/proc/sys/kernel/core_pattern. 我们知道在Linux系统中,如 ...