题目大意:
  有$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的更多相关文章

  1. [BZOJ2788][Poi2012]Festival

    2788: [Poi2012]Festival Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 187  Solved: 91[Submit][Statu ...

  2. [Poi2012]Festival 题解

    [Poi2012]Festival 时间限制: 1 Sec  内存限制: 64 MB 题目描述 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1. 给出a,b (1 ...

  3. [Poi2012]Festival 差分约束+tarjan

    差分约束建图,发现要在每个联通块里求最长路,600,直接O(n3) floyed #include<cstdio> #include<cstring> #include< ...

  4. 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 ...

  5. POI2012题解

    POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...

  6. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 2795: [Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 235[Subm ...

  9. [BZOJ2803][Poi2012]Prefixuffix

    2803: [Poi2012]Prefixuffix Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 219  Solved: 95[Submit][St ...

随机推荐

  1. win10系统安装之GHOST还原(转+编辑)

    注意*:在以下操作中,你可能需要分区你的原来系统盘,如果是重装的话.现在我们使用SSD固态做系统盘盘,这个分区的话,点选mbr重新引导,以及对齐复选框. 如果前面过程都没问题,在安装过程中出现    ...

  2. HDU 4655 Cut Pieces 找规律+简单计数

    解法参考:http://blog.csdn.net/a601025382s/article/details/9840125 #include <cstdio> #include <c ...

  3. 第二阶段团队冲刺-three

    昨天: 修复博客作业查询功能. 今天: 绘制logo. 遇到的问题: 无.

  4. [CF632E]Thief in a Shop

    题目大意:有一个小偷,拿$k$个东西,有$n$种产品,每种产品都有无限多个.对于每个第$i$ 种产品,它的价值是$A_i$.可能偷走的物品价值之和. 题解:对于所有的物品构造生成函数$F(x)=\su ...

  5. 70种简单常用的JS代码

    1.后退 前进      <input type="button" value="后退" onClick="history.go(-1)&quo ...

  6. python注解(装饰器)的用法

    带参数的要用三层def,第一层写注解里的参数,第二层写函数,第三层写具体逻辑. 如果是不带参数的注解,直接使用后两层即可 def needPermission(permissionstr): def ...

  7. CodeVs1515 跳

    题目描述 Description 邪教喜欢在各种各样空间内跳. 现在,邪教来到了一个二维平面.在这个平面内,如果邪教当前跳到了(x,y),那么他下一步可以选择跳到以下4个点:(x-1,y), (x+1 ...

  8. Dinic算法学习&&HDU2063

    http://www.cnblogs.com/SYCstudio/p/7260613.html 看这篇博文懂了一点,做题再体会体会吧 找了好久都没找到一个好用的模板…… 我也是佛了..最后决定用峰神的 ...

  9. eclipse非主窗口的停靠(正常), 恢复, 最小化, 最大化的切换

    1. pydev package Explorer的停靠与内嵌等 正常的情况

  10. penGL入门学习(六)

    http://blog.csdn.net/sun6255028/article/details/5090067 今天要讲的是动画制作——可能是各位都很喜欢的.除了讲授知识外,我们还会让昨天那个“太阳. ...