bzoj2788-Festival
题意
有 \(n\) 个变量,有两种限制,分别有 \(m_1,m_2\) 种。限制如下:
- \(a_x+1=a_y\)
- \(a_x\le a_y\)
求 \(\{x_i\}\) 集合的大小。\(n\le 600,m_1+m_2\le 10^5\) 。
分析
求集合大小其实就是最多有多少个变量不相同。看到这种变量的加减约束问题,首先想到了差分约束。
建边,若 \(a_x+1=a_y\) ,那么 \(a_x+1\ge a_y,a_y-1\ge a_x\) ,所以连边 \((x,y,1),(y,x,-1)\) 。
若 \(a_x\le a_y\) 那么连边 \((y,x,0)\) 。
先考虑一些特殊的情况。若出现非0的环,就说明出现了矛盾,排除掉这种情况。
对这个图缩环,那么形成了一个DAG,其中的边权值都为0,否则一定有一条跟它反向的边,那么就出现了一个新的环,与DAG定义不符。
那么每一个新点所代表的不同强连通分量之间的点的取值是不影响的。我们只需要考虑每一个的最多取值,全部加起来即可,因为总可以构造出不冲突的方案。
在一个强连通块中走出一条路径,就对应着一组可能的解。从第一个点开始标号,经过边权为1就加一,经过边权为-1就减一,经过边权为0就不变,这样我们得到的解一定是合法的,因为我们满足了所有的要求,而且我们已经排除了正权回路,即不会出现任何矛盾。同时我们得到的解一定是这条路径上从小到大标号中最优的,因为标号必定是连续的。同时,所有的解都能够在图上找到一条路径与之对应。
若这条路径的开头或结尾是-1,那么我们去掉这个,答案变优了,称这个操作为一次优化,那么对于一条路径,不断地优化,然后除去开头就是\((1,-1)\) 和结尾为 \((-1,1)\) 的,这样答案要么变优,要么不变。
最终我们得到了一条路径,这条路径是某两个点间的最短路,它的权值最大。这个权值的意义其实是终点减去起点的值的最大值。由于边权只有 \(\{-1,0,1\}\) ,所以每一个都会被取到。
综上,一个强连通块中的最多取值就是最短路中最长的+1 。
代码
发现之前的Tarjan写的不太对,ins[x] 数组应该在弹栈的时候标记为 false ,而不是退出dfs的时候。
#include<bits/stdc++.h>
using namespace std;
inline char nchar() {
static const int bufl=1<<20;
static char buf[bufl],*a,*b;
return a==b && (b=(a=buf)+fread(buf,1,bufl,stdin),a==b)?EOF:*a++;
}
inline int read() {
int x=0,f=1;
char c=nchar();
for (;!isdigit(c);c=nchar()) if (c=='-') f=-1;
for (;isdigit(c);c=nchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=605;
int n,d[maxn][maxn],col[maxn],cs=0,inf,ans[maxn];
int dfn[maxn],low[maxn],sta[maxn],top=0,dfx=0;
bool ins[maxn],mp[maxn][maxn];
inline void Max(int &x,int y) {x=max(x,y);}
inline void Min(int &x,int y) {x=min(x,y);}
void tarjan(int x) {
dfn[x]=low[x]=++dfx;
sta[++top]=x;
ins[x]=true;
for (int i=1;i<=n;++i) if (i!=x && mp[x][i]) {
if (!dfn[i]) tarjan(i),Min(low[x],low[i]); else
if (ins[i]) Min(low[x],dfn[i]);
}
if (dfn[x]==low[x]) {
++cs;
int v;
do col[v=sta[top--]]=cs,ins[v]=false; while (v!=x);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
n=read();
memset(d,0x3f,sizeof d);
inf=d[0][0];
for (int i=1;i<=n;++i) d[i][i]=0;
int m1=read(),m2=read();
while (m1--) {
int x=read(),y=read();
Min(d[x][y],1);
Min(d[y][x],-1);
mp[x][y]=mp[y][x]=true;
}
while (m2--) {
int x=read(),y=read();
Min(d[y][x],0);
mp[y][x]=true;
}
for (int k=1;k<=n;++k) for (int i=1;i<=n;++i) if (d[i][k]!=inf) for (int j=1;j<=n;++j) if (d[k][j]!=inf) Min(d[i][j],d[i][k]+d[k][j]);
for (int i=1;i<=n;++i) if (d[i][i]<0) puts("NIE"),exit(0);
for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
fill(ans+1,ans+cs+1,1);
for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) if (i!=j && col[i]==col[j]) Max(ans[col[i]],d[i][j]+1);
printf("%d\n",accumulate(ans+1,ans+cs+1,0));
return 0;
}
bzoj2788-Festival的更多相关文章
- [BZOJ2788][Poi2012]Festival
2788: [Poi2012]Festival Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 187 Solved: 91[Submit][Statu ...
- 【bzoj2788】Festival
Portal --> bzoj2788 Description 有\(n\)个正整数\(X_1,X_2,...,X_n\),再给出\(m1+m2\)个限制条件,限制分为两类: 1.给出\(a,b ...
- HDU1850 Being a Good Boy in Spring Festival(博弈)
Being a Good Boy in Spring Festival Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I ...
- hdu 1850 Being a Good Boy in Spring Festival(Nimm Game)
题意:Nimm Game 思路:Nimm Game #include<iostream> #include<stdio.h> using namespace std; int ...
- UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)
Saint John Festival 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/J Description Porto's ...
- reading words in your computer and changing to female voice, linux festival text2wave saving wav files
on a brand new linux PC, e.g. ubuntu 14.04 amd64 To hear voice sudo apt-get install festival -y then ...
- Being a Good Boy in Spring Festival(尼姆博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...
- Being a Good Boy in Spring Festival(杭电1850)(尼姆博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- 「AtCoder Grand018B」Sports Festival(暴力)
题目链接B - Sports Festival 题意 n(1~300)个人m(1~300)个活动,\(A_{ij}\)表示i第j喜欢的活动,每个人选择在举办的活动里最喜欢的,因此可以通过选择一些活动来 ...
- HDU 1850 Being a Good Boy in Spring Festival (Nim博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
随机推荐
- 图论-求有向图的强连通分量(Kosaraju算法)
求有向图的强连通分量 Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序 ...
- MSP430FR6972的串口波特率设置代码
1. 本次使用ACLK,就是辅助时钟(32.768KHZ)作为串口的时钟源,那么使用波特率9600的时候,分频系数=32768/9600=3.41,所以是有小数位的,设置代码如下 UCA0CTLW0 ...
- Sqlite数据多表联合update
其实在Mysql中,多表联合update不是什么难事. 语法: 1 UPDATE table_references SET col_name1=expr1 [, col_name2=expr2 ... ...
- Redis的事物
Redis的事物 Redis 事物常用命令 multi标记一个事物块的开始 exec:执行所有事物块内的命令 discard: 取消事物,放弃执行事物块的所有命令 watch key [k ...
- ffmpeg 踩坑实录 近期使用总结(三)
一.背景介绍 将ffmpeg运用到项目上已经有一段时间了,趁现在有空赶紧记下来. 二.技术点总结 2.1 实现方式 项目里面主要运用的形式是,在java端,调用操作系统的方法,并执行切片命令. ...
- 自己做的一个固定大小对象内存池,效率大概为原始的new/delete的2倍
提升不高,不过好处是可以多次申请小对象,一次释放.(只适应于无动态申请资源的class) vs2012测试情况如下: // CHchFixLenMemPool.h #pragma once #ifnd ...
- qs.js - 更好的处理url参数
第一次接触 qs 这个库,是在使用axios时,用于给post方法编码,在使用过程中,接触到了一些不同的用法,写在这里分享一下. qs.parse qs.parse 方法可以把一段格式化的字符串转换为 ...
- C#入门经典第十章例题 - - 卡牌
1.库 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...
- VS默认的类前缀(访问控制符)是internal
VS默认的类前缀(访问控制符)是internal 大家都知道VS默认新建的class的时候,class前面是什么都没有的,按照规则,这个class的可见性是internal,但是说实话,很多人包括我在 ...
- 天马行空-Ops平台建设概述
1 概述 什么是Ops平台,Ops平台的目标是什么,建设的考虑点有哪些?本章节以实际生活中医院的例子来进行各形象的阐述. 医院包含各种诊断治疗设备,病历库,医生.一个孕妇需要到医院 ...