[POI2012]Festival
题目大意:
有$n$个正整数$x_1,x_2,\ldots,x_n$,再给出一些限制条件,限制条件分为两类:
1.给出$A,B$,要求满足$X_A+1=X_B$;
2.给出$C,D$,要求满足$X_C\leq X_D$。
其中第1类限制条件有$m_1$个,第2类限制条件有$m_2$个。
问这些限制条件是否能都被满足,如果能,求集合$\{x_i\}$大小的最大值。
思路:
不难想到这是一个差分约束模型。
对于第1类限制,连一条权值为$1$的边$A\to B$,和一条权值为$-1$的边$B\to A$。
对于第2类限制,连一条权值为$0$的边$C\to D$。
这种连边方法很经典,难点在于连边以后如何求出集合大小的最大值。
对于同一个SCC,我们只要跑一下最长路就可以唯一确定当前SCC的权值集合大小,因此我们可以先跑一遍Tarjan,然后Floyd求最长路。
考虑不同SCC的关系。
Tarjan缩完点以后就变成了一个DAG,且DAG上的边一定对应第2类限制(不然一定对称,就变成SCC了)。
我们不妨假设不同SCC中的权值互不重叠,那么我们只需要将所有SCC的答案加起来即可。
#include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=;
struct Edge {
int to,w;
};
bool ins[N];
std::stack<int> s;
std::vector<Edge> e[N];
int dis[N][N],low[N],dfn[N],scc[N];
inline void add_edge(const int &u,const int &v,const int &w) {
e[u].push_back((Edge){v,w});
}
void tarjan(const int &x) {
low[x]=dfn[x]=++dfn[];
s.push(x);
ins[x]=true;
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(!dfn[y]) {
tarjan(y);
low[x]=std::min(low[x],low[y]);
} else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x]) {
scc[]++;
int y=;
while(y!=x) {
ins[y=s.top()]=false;
s.pop();
scc[y]=scc[];
}
}
}
int main() {
const int n=getint(),m1=getint(),m2=getint();
for(register int i=;i<=n;i++) {
for(register int j=;j<=n;j++) {
if(i!=j) {
dis[i][j]=-inf;
}
}
}
for(register int i=;i<m1;i++) {
const int u=getint(),v=getint();
add_edge(u,v,);
add_edge(v,u,-);
dis[u][v]=std::max(dis[u][v],);
dis[v][u]=std::max(dis[v][u],-);
}
for(register int i=;i<m2;i++) {
const int u=getint(),v=getint();
add_edge(u,v,);
dis[u][v]=std::max(dis[u][v],);
}
for(register int i=;i<=n;i++) {
if(!dfn[i]) {
tarjan(i);
}
}
int ans=;
for(register int c=;c<=scc[];c++) {
for(register int k=;k<=n;k++) {
if(scc[k]!=c) continue;
for(register int i=;i<=n;i++) {
if(scc[i]!=c||dis[i][k]==-inf) continue;
for(register int j=;j<=n;j++) {
if(scc[j]!=c||dis[k][j]==-inf) continue;
dis[i][j]=std::max(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
int tmp=;
for(register int i=;i<=n;i++) {
if(scc[i]!=c) continue;
for(register int j=;j<=n;j++) {
if(scc[j]!=c) continue;
tmp=std::max(tmp,std::abs(dis[i][j]));
}
}
ans+=tmp+;
}
for(register int i=;i<=n;i++) {
if(dis[i][i]) {
puts("NIE");
return ;
}
}
printf("%d\n",ans);
return ;
}
[POI2012]Festival的更多相关文章
- [BZOJ2788][Poi2012]Festival
2788: [Poi2012]Festival Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 187 Solved: 91[Submit][Statu ...
- [Poi2012]Festival 题解
[Poi2012]Festival 时间限制: 1 Sec 内存限制: 64 MB 题目描述 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1. 给出a,b (1 ...
- [Poi2012]Festival 差分约束+tarjan
差分约束建图,发现要在每个联通块里求最长路,600,直接O(n3) floyed #include<cstdio> #include<cstring> #include< ...
- bzoj 2788 [Poi2012]Festival 差分约束+tarjan+floyd
题目大意 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1.给出a,b (1<=a,b<=n),要求满足Xa + 1 = Xb 2.给出c,d (1&l ...
- POI2012题解
POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 2795: [Poi2012]A Horrible Poem
2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 484 Solved: 235[Subm ...
- [BZOJ2803][Poi2012]Prefixuffix
2803: [Poi2012]Prefixuffix Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 219 Solved: 95[Submit][St ...
随机推荐
- day04_08-while查询所有行
<?php $link = @mysql_connect('localhost','root',''); mysql_query('use test',$link); mysql_query(' ...
- 深入探讨ui框架
深入探讨前端UI框架 1 前言 先说说这篇文章的由来 最近看riot的源码,发现它很像angular的dirty check,每个component ( tag )都保存一个expressions数组 ...
- 哈夫曼树(C++优先队列的使用)
给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近. 构造 假设有n个权 ...
- 后端model传入前端JSP页面中的值判断后再取值
所遇到的问题后端model传入前端JSP页面中的值通过foreach循环内要满足条件才能取值给Div中,我们知道jsp页面中可以直接用EL表达式取值,格式就是${"model中传来的数据&q ...
- 洛谷 P2375 [NOI2014]动物园 解题报告
P2375 [NOI2014]动物园 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定 ...
- Gym100286C Clock
不想打题面,题面戳这里. 被这题吓到了,感觉无从下手.最后还是看着题解和别人的代码加以改编最后写出了的.其实理解之后写出了也就是三四十行的样子了. 首先题目有个很重要的条件--转动某个针只会对周期比他 ...
- cdoj 1259 线段树+bitset 区间更新/查询
Description 昊昊喜欢运动 他N天内会参加M种运动(每种运动用一个[1,m]的整数表示) 现在有Q个操作,操作描述如下 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) 问昊昊第l天 ...
- div盒子模型(一图胜千言)
offsetLeft 获取的是相对于父对象的左边距 left 获取或设置相对于 具有定位属性(position定义为relative)的父对象 的左边距 如果父div的position定义为relat ...
- python常用20库
python核心库和统计 简述 1. Requests.最着名的http库由kenneth reitz编写.这是每个python开发人员必备的. 2. Scrapy.如果您参与webscraping, ...
- UVA 10652 Board Wrapping(二维凸包)
传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...