【bzoj2788】Festival
Description
有\(n\)个正整数\(X_1,X_2,...,X_n\),再给出\(m1+m2\)个限制条件,限制分为两类:
1、给出\(a,b (1<=a,b<=n)\),要求满足\(X_a + 1 = X_b\)
2、 给出\(c,d (1<=c,d<=n)\),要求满足\(X_c <= X_d\)
在满足所有限制的条件下,求集合\(\{X_i\}\)大小的最大值,如果无解输出"NIE"
数据范围$2<=n<=600, 1<=m1+m2<=100,000 $
Solution
同样也是。。借这题补个档:差分约束系统
差分约束系统的话是将形如\(x_i-x_j<=a\)这样的式子转化成有向图中的一条\(j\rightarrow i\)长度为\(a\)的边,然后对于一个不等式组,我们可以用这样的方式建一个有向图出来,不等式组中未知数\(x_j-x_i\)的最大值即为\(x_i\)到\(x_j\)的最短路径长度,如果说有向图中存在负环那么就是无解的情况,如果说不存在\(x_i\)到\(x_j\)的路径则有无数组解(因为这就说明这两个未知数之间没有约束关系)
具体一点的话这里举个小栗子例子方便理解
考虑这样一个“三角”不等式组:
B-A=c\\
C-B=a\\
C-A=b
\end{cases}
\]
然后我们可以建出这样的一个有向图:
然后我们考虑一下\(C-A\)的最大值,从式子来看应该是\(min(b,a+c)\),所以就是\(A\)到\(C\)的最短路,式子更多的情况也是一样的
这里贴一个整理比较全的博(各种题目qwq):Portal
然后我们回到这道题
这题的那个式子。。长得就是差分约束系统的样子qwq,只不过我们需要稍微处理一下:
x<=y\Leftrightarrow x-y<=0\\
\]
然后建出有向图,然后我们通过负环就可以直接判掉无解的情况了
接下来只考虑有解的情况
为了方便思考我们先假装已经缩好了点,每个点代表一个强联通分量
这时这个新图里面一定没有环了,并且由于我们的建图方式,所以我们可以肯定缩完点之后的图中所有的边权都是\(0\),否则一定会有一条反向的边,那就与缩完点的性质矛盾了(这个性质十分关键)
我们可以发现,由于题目要求的是集合大小,也就是不同的元素个数,如果两个点不在同一个强联通分量里面,那么这两个点的取值一定能构造出一种答案使得两个点的取值不同,再推广一下,我们会发现其实两个强联通分量对答案的贡献是不会相互影响的,也就是说我们只需要将每个强联通分量的答案算出来然后最后求和就可以得到最后的答案了
现在的问题是怎么求一个强联通分量内部的答案
我们挑一个强联通分量进行考虑,如果说我们挑的这个强联通分量中差值最大的两个数\(x_1,x_2\),假设他们的最大差值(也就是最短路)为\(a\)
考虑一下这个有向图的特殊性质:边权\(\in \{-1,0,1\}\),并且因为这个图除去强联通分量外不存在环了,所以强联通分量中的两个点之间的最短路一定走的是强联通分量中的边,所以如果说最大差值为\(a\)(也就是最短路长度为\(a\)),这条路径一定是由若干条\(0\),若干条\(1\),若干条\(-1\)的边构成的,而那就说明增大只能\(+1\)这样来增大,所以中间包含的所有的数一定都能被取到,也就是说有\(a+1\)个不同的数
所以一个强联通分量对答案的贡献就是\(a+1\)了,然后这题就十分愉快滴做完啦
一个小trick:因为这题的点数很少,所以我们可以直接用Floyd来求最短路(反正你查询的时候。。每个点出发的最短路都要查。。),判负环的话直接跑完Floyd之后看一下是否存在一个\(i\)满足\(dis[i][i]<0\)就好了
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=610,M=100010,inf=2147483647;
int dis[N][N],mp[N][N];
int h[N],dfn[N],low[N],st[N],inst[N],pre[N],mx[N];
int id[N];
int n,m1,m2,dfn_t,top,ans,cnt;
void tarjan(int x){
dfn[x]=low[x]=++dfn_t; inst[x]=1; st[++top]=x;
for (int i=1;i<=n;++i){
if (i==x||!mp[x][i]) continue;
if (!dfn[i]){
tarjan(i);
low[x]=min(low[i],low[x]);
}
else if (inst[i]){
low[x]=min(low[x],dfn[i]);
}
}
int u;
if (low[x]==dfn[x]){
++cnt; u=st[top];
while (u!=x){
id[u]=cnt;
inst[u]=false;
u=st[--top];
}
id[x]=cnt;
inst[u]=false;
--top;
}
}
int floyd(){
for (int k=1;k<=n;++k)
for (int i=1;i<=n;++i){
if (dis[i][k]==inf) continue;
for (int j=1;j<=n;++j){
if (dis[k][j]==inf) continue;
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
void add(int x,int y,int d){
dis[x][y]=min(dis[x][y],d);
mp[x][y]=true;
}
void solve(){
dfn_t=0; top=0;
for (int i=1;i<=n;++i)
if (!dfn[i]) tarjan(i);
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j){
if (i==j||id[i]!=id[j]) continue;
mx[id[i]]=max(mx[id[i]],dis[i][j]);
}
ans=0;
for (int i=1;i<=cnt;++i)
ans+=mx[i]+1;
printf("%d\n",ans);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y;
scanf("%d%d%d",&n,&m1,&m2);
memset(mp,false,sizeof(mp));
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
dis[i][j]=inf;
for (int i=1;i<=m1;++i){
scanf("%d%d",&x,&y);
add(x,y,1);//1<=y-x<=1
add(y,x,-1);
}
for (int i=1;i<=m2;++i){
scanf("%d%d",&x,&y);
add(y,x,0);//x-y<=0
}
floyd();
bool flag=true;
for (int i=1;i<=n&&flag;++i)
if (dis[i][i]<0) flag=false;
if (!flag){printf("NIE\n");return 0;}
solve();
}
【bzoj2788】Festival的更多相关文章
- 【题解】Music Festival(树状数组优化dp)
[题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...
- 【Atcoder】CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning
[题意]给定只含小写字母的字符串,要求分割成若干段使段内字母重组顺序后能得到回文串,求最少分割段数.n<=2*10^5 [算法]DP [题解]关键在于快速判断一个字符子串是否合法,容易发现合法仅 ...
- 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring
[题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...
- 【Java】-NO.20.Exam.1.Java.1.001- 【1z0-807】- OCEA
1.0.0 Summary Tittle:[Java]-NO.20.Exam.1.Java.1.001-[1z0-807] Style:EBook Series:Java Since:2017-10- ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
随机推荐
- MySQL事务、并发问题、锁机制
MySQL事务,并发问题,锁机制 1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库 ...
- 多重共性和VIF检验
图片来源https://wenku.baidu.com/view/7008df8383d049649b66581a.html 和 https://wenku.baidu.com/view/6acdf9 ...
- 创建image
摘要: 本节演示如何通过 Web GUI 和 CLI 两种方法创建 Image. 本节演示如何通过 Web GUI 和 CLI 两种方法创建 Image. OpenStack 为终端用户提供了 Web ...
- Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut
cat 查看文件内容 [root@mysql tmp]# cat 2.txt 1234 -n 查看行号 [root@mysql tmp]# cat -n 2.txt 1 1234 ...
- 1.airflow的安装
1.环境准备1.1 安装环境1.2 创建用户2.安装airflow2.1 安装python2.2 安装pip2.3 安装数据库2.4 安装airflow2.4.1 安装主模块2.4.2 安装数据库模块 ...
- LCA最近公共祖先(Tarjan离线算法)
这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...
- Beautiful Year(拆分四位数)
Description It seems like the year of 2013 came only yesterday. Do you know a curious fact? The year ...
- Java连接池
- 解决Ubuntu16.04 fatal error: json/json.h: No such file or directory
参考博客 错误产生 安装json-c库之后,根据GitHub上面的readme文件链接到json-c库时出现以下错误: SDMBNJson.h:9:23: fatal error: json/json ...
- 团队展示(I know)
一.队员姓名与学号 姓名 学号 组长 陈家权 031502107 赖晓连 031502118 ★ 雷晶 031502119 林巧娜 031502125 庄加鑫 031502147 二.队名 I kno ...