题面甚至没给范围,由数据可得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)的更多相关文章

  1. BZOJ 4078: [Wf2014]Metal Processing Plant

    4078: [Wf2014]Metal Processing Plant Time Limit: 100 Sec  Memory Limit: 128 MBSubmit: 86  Solved: 20 ...

  2. CH Round #72树洞[二分答案 DFS&&BFS]

    树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...

  3. [CF752E]Santa Claus and Tangerines(二分答案,dp)

    题目链接:http://codeforces.com/contest/752/problem/E 题意:给n个橘子,每个橘子a(i)片,要分给k个人,问每个人最多分多少片.每个橘子每次对半分,偶数的话 ...

  4. [NOIP2011] 聪明的质检员(二分答案)

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...

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

  6. {POJ}{3897}{Maze Stretching}{二分答案+BFS}

    题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...

  7. Leetcode 4 Median of Two Sorted Arrays 二分查找(二分答案+二分下标)

    貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的... 题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数. 二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第 ...

  8. CF 371C-Hamburgers[二分答案]

    C. Hamburgers time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. NOIP2015跳石头[二分答案]

    题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选 择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石( ...

随机推荐

  1. 蓝桥杯之剪格子(经典dfs)

    如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |10* 1|52| +--****--+ |20|30* 1| *******--+ | 1| 2| 3| +--+--+-- ...

  2. centos 7 163 yum 源 python 2.7.5

    安装 repo 源. repo 源一般包括 base, updates, Extras 三部分. $ cd /etc/yum.repos.d/ $ wget http://mirrors.163.co ...

  3. C# 自定义类型转换

    1.显式转换和隐式转换: ; long b=a; // 从int到long的隐式转换 int c=(int) b; // 从long到int是显式转换 ------------------------ ...

  4. 如何测试Oracle并行执行的并行度状况

    如何测试Oracle并行执行的并行度状况: 可以通过如下的脚本,来查看要求的并行度,和实际获得的并行度. 脚本来自: http://askdba.org/weblog/forums/topic/que ...

  5. 利用OVS+FLOODLIGHT,为数据表添加VLAN_ID和MPLS

    话不多说,直接上拓扑: 我这里是用主机h1 (10.0.0.1)ping 主机h2(10.0.0.2) 1.添加VLAN标签 v1: sudo ovs-ofctl add-flow m1-s1 in_ ...

  6. python3 简单进度条代码

    进度条代码函数实现 import sys, time class ShowProcess(object): """ 显示处理进度的类 调用该类相关函数即可实现处理进度的显 ...

  7. .NET Core 开发之旅 (1. .NET Core R2安装教程及Hello示例)

    前言 前几天.NET Core发布了.NET Core 1.0.1 R2 预览版,之前想着有时间尝试下.NET Core.由于各种原因,就没有初试.刚好,前几天看到.NET Core发布新版本了,决定 ...

  8. Jmeter(八)-发送JDBC请求

    下午花了两个小时研究了一下Jmeter发送JDBC请求,现在把基本操作流程分享一下. 做JDBC请求,首先需要两个jar包:mysql驱动-mysql-connector-java-5.1.13-bi ...

  9. .netCoreMVC添加数据仓储

    在上一篇关于CodeFirst从零搭建ASP.NETCore2.0中搭建起了完整.netCoreMVC项目,在这一篇中将实现如何注册service服务和Repository数据仓储到web中实现数据的 ...

  10. Dictionary 对象

    Dictionary 对象 对象的存储数据键/项对. 语法 Scripting.Dictionary 说明 Dictionary对象相当于 PERL 关联数组. 项目,可以是任何形式的数据,存储在数组 ...