BZOJ4078 WF2014Metal Processing Plant(二分答案+2-SAT)
题面甚至没给范围,由数据可得n<=200。容易想到二分答案,暴力枚举某集合的价值,2-SATcheck一下即可。这样是O(n4logn)的。
2-SAT复杂度已经是下界,考虑如何优化枚举。稍微改一下,不妨从大到小枚举较大的集合价值(即枚举边),另一个集合二分答案,同样O(n4logn)。
看起来没什么卵用。但注意到较大集合所不能包含的边不可以成奇环,否则肯定有一条环上边被选中。那么考虑当前边,如果形成奇环,最大值不可能比它更小了,做完这个就可以退出;如果加上这条边后形成偶环,可以直接跳过,因为如果要让其被选中,相当于将偶环缩成了奇环,剩余边肯定有一条被选中而又比它大。不形成环时则直接做。由于树边数量O(n),复杂度O(n3logn)。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define ll long long
#define N 210
#define inf 1000000010
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,a[N][N],b[N*N],dfn[N<<],low[N<<],stk[N<<],belong[N<<],p[N<<],fa[N<<],deep[N<<],size[N<<],len[N<<],t,top,tot,cnt,ans=inf,m;
bool flag[N<<];
struct data{int to,nxt;
}edge[N*N<<];
struct data2
{
int x,y,z;
bool operator <(const data2&a) const
{
return z<a.z;
}
}e[N*N];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void tarjan(int k)
{
dfn[k]=low[k]=++cnt;
stk[++top]=k;flag[k]=;
for (int i=p[k];i;i=edge[i].nxt)
if (!dfn[edge[i].to]) tarjan(edge[i].to),low[k]=min(low[k],low[edge[i].to]);
else if (flag[edge[i].to]) low[k]=min(low[k],dfn[edge[i].to]);
if (dfn[k]==low[k])
{
tot++;
while (stk[top]!=k)
{
flag[stk[top]]=;
belong[stk[top]]=tot;
top--;
}
flag[k]=,belong[k]=tot,top--;
}
}
bool check(int x,int y)
{
memset(dfn,,sizeof(dfn));
memset(p,,sizeof(p));t=tot=cnt=;
for (int i=;i<n;i++)
for (int j=i+;j<=n;j++)
{
if (a[i][j]>x) addedge(i*-,j*),addedge(j*-,i*);
if (a[i][j]>y) addedge(i*,j*-),addedge(j*,i*-);
}
for (int i=;i<=n*;i++)
if (!dfn[i]) tarjan(i);
for (int i=;i<=n;i++) if (belong[i*-]==belong[i*]) return ;
return ;
}
int find(int x)
{
if (fa[x]==x) return x;
int f=find(fa[x]);
deep[x]=deep[fa[x]]^len[x];
return f;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4078.in","r",stdin);
freopen("bzoj4078.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<n;i++)
for (int j=i+;j<=n;j++)
{
a[i][j]=a[j][i]=read();
m++;e[m].z=a[i][j],e[m].x=i,e[m].y=j;
}
sort(e+,e+m+);
for (int i=;i<=n*;i++) fa[i]=i,size[i]=;
for (int i=m;i>=;i--)
{
int p=find(e[i].x),q=find(e[i].y);
if (size[p]<size[q]) swap(p,q);
if (p!=q||(deep[e[i].x]^deep[e[i].y]^))
{
if (p!=q) fa[q]=p,size[p]+=size[q],len[q]=deep[e[i].x]^deep[e[i].y]^;
int l=,r=i,u=inf;
while (l<=r)
{
int mid=l+r>>;
if (check(e[i].z,e[mid].z)) u=e[mid].z,r=mid-;
else l=mid+;
}
ans=min(ans,e[i].z+u);
}
if (p==q&&(deep[e[i].x]^deep[e[i].y]^)) break;
}
if (ans==inf) ans=;cout<<ans;
return ;
}
BZOJ4078 WF2014Metal Processing Plant(二分答案+2-SAT)的更多相关文章
- BZOJ 4078: [Wf2014]Metal Processing Plant
4078: [Wf2014]Metal Processing Plant Time Limit: 100 Sec Memory Limit: 128 MBSubmit: 86 Solved: 20 ...
- CH Round #72树洞[二分答案 DFS&&BFS]
树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...
- [CF752E]Santa Claus and Tangerines(二分答案,dp)
题目链接:http://codeforces.com/contest/752/problem/E 题意:给n个橘子,每个橘子a(i)片,要分给k个人,问每个人最多分多少片.每个橘子每次对半分,偶数的话 ...
- [NOIP2011] 聪明的质检员(二分答案)
题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...
- Codeforces Round #377 (Div. 2) D. Exams(二分答案)
D. Exams Problem Description: Vasiliy has an exam period which will continue for n days. He has to p ...
- {POJ}{3897}{Maze Stretching}{二分答案+BFS}
题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...
- Leetcode 4 Median of Two Sorted Arrays 二分查找(二分答案+二分下标)
貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的... 题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数. 二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第 ...
- CF 371C-Hamburgers[二分答案]
C. Hamburgers time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- NOIP2015跳石头[二分答案]
题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选 择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石( ...
随机推荐
- SQL 字符串分割表函数
--字符串分割表函数 ) ) declare @i int; declare @count int; ); ); declare @Index int; )) declare @rowID int; ...
- Debuggex – 超好用的正则表达式可视化调试工具
正则表达式通常被用来检索或替换符合某个模式的文本内容,编写正则是开发人员的必备技能.简单的正则表达式一下就能看懂含义,但是复杂的正则理解起来就很困难了.有了这款可视化的正则调试工具,以后编写正则表达式 ...
- AbelSu玩Kotlin
Kotlin是一门基于JVM的编程语言,它正成长为Android开发中用于替代Java语言的继承者. Kotlin是由JetBrains创建的基于JVM的编程语言,IntelliJ正是JetBrain ...
- Java基础—常用类之String类
一.String类是什么 public final class String implements java.io.Serializable, Comparable<String>, Ch ...
- 【php增删改查实例】第七节 - 部门管理模块(画一个datagrid表格)
在easyui中,datagrid组件需要用一个table标签去渲染. <table id="grid0" title="部门管理" class=&quo ...
- Hadoop日记Day5---HDFS介绍
一.HDFS介绍 1.1 背景 随着数据量越来越大,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式 ...
- Linux 学习日记 2 (常用命令 + deb包的安装)
常用命令:以下是一些比较常用的命令,主要是关于安装软件的一些命令 @_@ cd ~/下载(文件名)/ //进入这个文件夹 , ~指的是根目录 cd .. //返回上一级文件夹 sudo apt-get ...
- react脚手架改造(react/react-router/redux/eslint/karam/immutable/es6/webpack/Redux DevTools)
公司突然组织需要重新搭建一个基于node的论坛系统,前端采用react,上网找了一些脚手架,或多或少不能满足自己的需求,最终在基于YeoMan的react脚手架generator-react-webp ...
- [PLC]ST语言四:INV_MEP_MEF_PLS_PLF_MC_MCR
一:INV_MEP_MEF_PLS_PLF_MC_MCR 说明:简单的顺控指令不做其他说明. 控制要求:无 编程梯形图: 结构化编程ST语言: (*运算结果的反转INV(EN);*) M415:=in ...
- OD之去除nag弹窗(四)
在某些方面,一个软件如果没有注册的话,老是会弹出烦人的注册弹窗,就如下图一样: 出现了两次弹窗,开始一次,关闭后又一次,老办法,拖进OD进行分析;不过看出程序很简单,就出现了messagebox的调用 ...