[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 ...
随机推荐
- win10系统安装之GHOST还原(转+编辑)
注意*:在以下操作中,你可能需要分区你的原来系统盘,如果是重装的话.现在我们使用SSD固态做系统盘盘,这个分区的话,点选mbr重新引导,以及对齐复选框. 如果前面过程都没问题,在安装过程中出现 ...
- HDU 4655 Cut Pieces 找规律+简单计数
解法参考:http://blog.csdn.net/a601025382s/article/details/9840125 #include <cstdio> #include <c ...
- 第二阶段团队冲刺-three
昨天: 修复博客作业查询功能. 今天: 绘制logo. 遇到的问题: 无.
- [CF632E]Thief in a Shop
题目大意:有一个小偷,拿$k$个东西,有$n$种产品,每种产品都有无限多个.对于每个第$i$ 种产品,它的价值是$A_i$.可能偷走的物品价值之和. 题解:对于所有的物品构造生成函数$F(x)=\su ...
- 70种简单常用的JS代码
1.后退 前进 <input type="button" value="后退" onClick="history.go(-1)&quo ...
- python注解(装饰器)的用法
带参数的要用三层def,第一层写注解里的参数,第二层写函数,第三层写具体逻辑. 如果是不带参数的注解,直接使用后两层即可 def needPermission(permissionstr): def ...
- CodeVs1515 跳
题目描述 Description 邪教喜欢在各种各样空间内跳. 现在,邪教来到了一个二维平面.在这个平面内,如果邪教当前跳到了(x,y),那么他下一步可以选择跳到以下4个点:(x-1,y), (x+1 ...
- Dinic算法学习&&HDU2063
http://www.cnblogs.com/SYCstudio/p/7260613.html 看这篇博文懂了一点,做题再体会体会吧 找了好久都没找到一个好用的模板…… 我也是佛了..最后决定用峰神的 ...
- eclipse非主窗口的停靠(正常), 恢复, 最小化, 最大化的切换
1. pydev package Explorer的停靠与内嵌等 正常的情况
- penGL入门学习(六)
http://blog.csdn.net/sun6255028/article/details/5090067 今天要讲的是动画制作——可能是各位都很喜欢的.除了讲授知识外,我们还会让昨天那个“太阳. ...