枚举从大到小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+枚举+并查集】的更多相关文章

  1. BZOJ 4078: [Wf2014]Metal Processing Plant

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

  2. BZOJ 4078: [Wf2014]Metal Processing Plant [放弃了]

    以后再也不做$World Final$的题了................ 还我下午 bzoj上TLE一次后就不敢交了然后去uva交 Claris太神了代码完全看不懂 还有一个代码uva上竟然WA了 ...

  3. 【刷题】BZOJ 4078 [Wf2014]Metal Processing Plant

    Description 定义集合S的价值D(S)为: 现在给你n个元素,并给出其中任意两个元素之间的d(i,j)值 要你将这些元素划分成两个集合A.B. 求min{D(A)+D(B)}. 注:d(i, ...

  4. BZOJ4078 : [Wf2014]Metal Processing Plant

    设$D(A)\leq D(B)$,从小到大枚举$D(A)$,双指针从大到小枚举$D(B)$. 那么对于权值不超过$D(A)$的边,可以忽略. 对于权值介于$(D(A),D(B)]$之间的边,需要满足那 ...

  5. noip 2010 关押罪犯 二分答案+二分图染色 || 并查集

    题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...

  6. Codeforces Gym 101221G Metal Processing Plant(2-SAT)

    题目链接 题意:有 \(n\) 个元素,第 \(i\) 个数与第 \(j\) 个数之间有一个权值 \(d_{i,j}\),\(d(i,j)=d(j,i)\). 定义函数 \(D(S)=\max\lim ...

  7. bzoj 1682: [Usaco2005 Mar]Out of Hay 干草危机【并查集+二分】

    二分答案,把边权小于mid的边的两端点都并起来,看最后是否只剩一个联通块 #include<iostream> #include<cstdio> using namespace ...

  8. BZOJ 1202 狡猾的商人 差分约束or带权并查集

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1202 题目大意: 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的 ...

  9. BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集

    http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...

随机推荐

  1. windows7 下安装使用memcached(二)

    Memcached 安装使用 本地环境:Windows7 64位web环境:wamp集成环境,php版本:PHP Version 7.1.17 学习参考网站: RUNOOB.COM官网  http:/ ...

  2. [vijos1891]学姐的逛街计划

                                                                     学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, d ...

  3. Android中传递对象的三种方法

    Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! Android中,Activity和Fragment之间传递对象,可以通过将对象序列化并存入Bundle或者I ...

  4. ln 软连接 & 硬连接

    创建软连接的方式 #ln -s soure /file object 创建软连接是连接文件本身,可以跨分区建立软连接,不会应为不同分区而出现不能使用的问题. 在创建软连接的文件中,修改一处文件另一处同 ...

  5. DosBox 报错 this program requires dosxnt.exe to be in your path

    也就是少了dosxnt.exe文件,能够上网搜索下载,把dosxnt 拷贝到你挂截文件夹下就能够执行 Dosxnt文件下载

  6. wpf 导出Excel Wpf Button 样式 wpf简单进度条 List泛型集合对象排序 C#集合

    wpf 导出Excel   1 private void Button_Click_1(object sender, RoutedEventArgs e) 2 { 3 4 ExportDataGrid ...

  7. I2S简单学习

    以下只是个人看法,有不妥之处,请批评指出. 参考资料:http://blog.csdn.net/ce123_zhouwei/article/details/6919954: 一.I2S接口简述 I²S ...

  8. C语言将10进制转为2进制

    第一种方法: #include<stdio.h> void dectobin(int n); int main() { int x=0; scanf("%d",& ...

  9. 在线生成32位和16位大小写MD5密文

    MD5是一种不可逆的加密算法,全称是Message-Digest Algorithm 5(信息-摘要算法).是当前计算机领域用于确保信息传输完整一致而广泛使用的散列算法之一. MD5的典型应用是对一段 ...

  10. 关于OutOfMemoryError的处理

    转自:http://www.blogjava.net/rosen/archive/2010/05/21/321575.html http://www.blogjava.net/rosen/archiv ...