bzoj 4078: [Wf2014]Metal Processing Plant【二分+2-SAT+枚举+并查集】
枚举从大到小s1,二分s2(越大越有可能符合),2-SAT判断,ans取min
思路倒是挺简单的,就是二分的时候出了比较诡异的问题,只能二分s2的值,不能在数组上二分...
有个优化,就是当不是二分图的时候退出枚举,这个用并查集染色维护
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=405;
int n,a[N][N],tot,has,h[N],cnt,ans=2e9,f[N],d[N],dfn[N],low[N],s[N],top,bl[N],dft,col;
bool v[N];
struct qwe
{
int ne,to,va;
}e[N*N];
struct bian
{
int u,v,w;
}b[N*N];
bool cmp(const bian &a,const bian &b)
{
return a.w>b.w||(a.w==b.w&&a.u>b.u)||(a.w==b.w&&a.u==b.u&&a.v>b.v);
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
inline int zhao(int x)
{
if(f[x]==x)
return x;
int res=zhao(f[x]);
d[x]^=d[f[x]];
return f[x]=res;
}
void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void tarjan(int u)
{
low[u]=dfn[u]=++dft;
v[s[++top]=u]=1;
for(int i=h[u];i;i=e[i].ne)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[u]=min(low[u],low[e[i].to]);
}
else if(v[e[i].to])
low[u]=min(low[u],dfn[e[i].to]);
}
if(dfn[u]==low[u])
{
col++;
while(s[top]!=u)
{
bl[s[top]]=col;
v[s[top--]]=0;
}
bl[s[top]]=col;
v[s[top--]]=0;
}
}
bool ok(int s1,int s2)
{
memset(h,0,sizeof(h));
memset(dfn,0,sizeof(dfn));
cnt=0;dft=0;col=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(a[i][j]>s1)
add(i+n,j),add(j+n,i);
if(a[i][j]>s2)
add(i,j+n),add(j,i+n);
}
for(int i=1;i<=n+n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
if(bl[i]==bl[i+n])
return 0;
return 1;
}
void wk(int c)
{
// int l=c,r=tot,an=0;
// while(l<=r)
// {
// int mid=(l+r)>>1;
// if(ok(b[c].w,b[mid].w))
// l=mid+1,an=mid;
// else
// r=mid-1;
// }
// if(an)
// ans=min(ans,b[c].w+b[an].w);
int l=0,r=b[c].w;
while(l<=r)
{
int mid=(l+r)>>1;
if(ok(b[c].w,mid))
r=mid-1;
else
l=mid+1;
}
ans=min(ans,b[c].w+l);
}
int main()
{
n=read();
if(n<=2)
{
puts("0");
return 0;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
a[i][j]=a[j][i]=read();
b[++tot]=(bian){i,j,a[i][j]};
}
sort(b+1,b+1+tot,cmp);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=tot;i++)
{
int fu=zhao(b[i].u),fv=zhao(b[i].v);
if(fu!=fv)
{
wk(i);
d[fu]=d[b[i].u]^d[b[i].v]^1;
f[fu]=fv;
}
else if(d[b[i].u]==d[b[i].v])
{
wk(i);
break;
}
}
printf("%d\n",ans);
return 0;
}
bzoj 4078: [Wf2014]Metal 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 ...
- BZOJ 4078: [Wf2014]Metal Processing Plant [放弃了]
以后再也不做$World Final$的题了................ 还我下午 bzoj上TLE一次后就不敢交了然后去uva交 Claris太神了代码完全看不懂 还有一个代码uva上竟然WA了 ...
- 【刷题】BZOJ 4078 [Wf2014]Metal Processing Plant
Description 定义集合S的价值D(S)为: 现在给你n个元素,并给出其中任意两个元素之间的d(i,j)值 要你将这些元素划分成两个集合A.B. 求min{D(A)+D(B)}. 注:d(i, ...
- BZOJ4078 : [Wf2014]Metal Processing Plant
设$D(A)\leq D(B)$,从小到大枚举$D(A)$,双指针从大到小枚举$D(B)$. 那么对于权值不超过$D(A)$的边,可以忽略. 对于权值介于$(D(A),D(B)]$之间的边,需要满足那 ...
- noip 2010 关押罪犯 二分答案+二分图染色 || 并查集
题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...
- Codeforces Gym 101221G Metal Processing Plant(2-SAT)
题目链接 题意:有 \(n\) 个元素,第 \(i\) 个数与第 \(j\) 个数之间有一个权值 \(d_{i,j}\),\(d(i,j)=d(j,i)\). 定义函数 \(D(S)=\max\lim ...
- bzoj 1682: [Usaco2005 Mar]Out of Hay 干草危机【并查集+二分】
二分答案,把边权小于mid的边的两端点都并起来,看最后是否只剩一个联通块 #include<iostream> #include<cstdio> using namespace ...
- BZOJ 1202 狡猾的商人 差分约束or带权并查集
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1202 题目大意: 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的 ...
- BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集
http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...
随机推荐
- C# Queue与RabbitMQ的爱恨情仇(文末附源码):Q与MQ消息队列简单应用(二)
上一章我们讲了队列( Queue),这一章我们讲Message Queue消息队列,简称MQ. 定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开 ...
- CEF3研究(四)之javascript集成
一.介绍 谷歌浏览器和CEF使用V8JavaScript Engine作为内容的JavaScript实现.在浏览器中的每个窗口都有它自己在的JS上下文提供作用域和在窗口中安全的执行JS代码.CEF暴露 ...
- 【CODEFORCES】 C. Dreamoon and Strings
C. Dreamoon and Strings time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Lnixu Bash
一.简单命令 1.创建文件(vi) vi hellowold.txt2.创建目录(mkdir) mkdir linux_bash3.删除文件(rm) rm helloworld.txt4.复制文件(c ...
- (原创)EasyUI中datagrid的行编辑模式中,找到特定的Editor,并为其添加事件
有时候在行编辑的时候,一个编辑框的值要根据其它编辑框的值进行变化,那么可以通过在开启编辑时,找到特定的Editor,为其添加事件 // 绑定事件, index为当前编辑行 var editors = ...
- NHibernate查询导致Update问题
用NHibernate,总感觉怪事多罗罗. 比如说,明明我们是在查询,却报错,刨根问底找到出错原因,竟然是因为执行了一些Update甚至Insert!老天,我们明明只是查询而已,什么时候有更新过数据? ...
- setTimeout不可靠的修正办法及clearTimeout
javascript里的这两个定时器函数,大家一定耳熟能详: setTimeout("函数()",毫秒)就是开启一个计时器,指定毫秒后执行该函数一次. 有关定时器,javascri ...
- web框架和Django框架的初识
1,web框架的原理 1.1>c/s架构和b/s架构 1>c/s客户端模式 2>B/S浏览器模式-----web开发(web开发开的是B/S架构) 1.2>web开发的本质 1 ...
- linux 多个文件中查找字符串 hadoop 3 安装 调试
http://www.cnblogs.com/iLoveMyD/p/4281534.html 2015年2月9日 14:36:38 # find <directory> -type f - ...
- String StringBuffer StringBuilder 对比
1.StringBuffer是线程安全的,StringBuilder是非线程安全的 2.对String的修改其实是new了一个StringBuilder并调用append方法,然后调用toSt ...