bzoj4078
二分+2-sat
枚举第一个权值,二分第二个权值,然后2-sat检查,当第一个权值已经不能形成二分图时,再往下没意义,因为没法分成两个点集。(双指针好像跑得慢)
#include<bits/stdc++.h>
using namespace std;
const int N = ;
struct edge {
int u, v, w;
edge(int u = , int v = , int w = ) : u(u), v(v), w(w) {}
bool friend operator < (edge A, edge B)
{
return A.w > B.w;
}
} e[N * N];
int n, tot, cnt, all, top, ans;
int dfn[N], low[N], st[N], belong[N], vis[N], Map[N][N], color[N], fa[N], d[N];
vector<int> G[N], g[N];
int find(int x)
{
if(fa[x] == x) return x;
int ret = find(fa[x]);
d[x] ^= d[fa[x]];
return fa[x] = ret;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++cnt;
st[++top] = u;
vis[u] = ;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v]) low[u] = min(low[u], low[v]);
}
if(low[u] == dfn[u])
{
++all;
int j;
while()
{
j = st[top];
belong[j] = all;
vis[j] = ;
--top;
if(j == u) break;
}
}
}
bool check(int x, int y)
{
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(vis, , sizeof(vis));
top = ;
cnt = ;
all = ;
if(x > y) swap(x, y);
for(int i = ; i <= * n; ++i)
G[i].clear();
for(int i = ; i <= tot; ++i)
{
if(e[i].w > y)
{
G[e[i].u].push_back(e[i].v + n);
G[e[i].v].push_back(e[i].u + n);
G[e[i].u + n].push_back(e[i].v);
G[e[i].v + n].push_back(e[i].u);
}
else if(e[i].w > x)
{
G[e[i].u].push_back(e[i].v + n);
G[e[i].v].push_back(e[i].u + n);
}
}
for(int i = ; i <= * n; ++i) if(!dfn[i]) tarjan(i);
for(int i = ; i <= n; ++i) if(belong[i] == belong[i + n]) return false;
return true;
}
int main()
{
scanf("%d", &n);
for(int i = ; i <= n; ++i) fa[i] = i;
for(int i = ; i < n; ++i)
for(int j = ; j <= n - i; ++j)
{
scanf("%d", &Map[i][i + j]);
e[++tot] = edge(i, i + j, Map[i][i + j]);
}
if(n == )
{
puts("");
return ;
}
++tot;
sort(e + , e + tot + );
ans = ;
int j = tot;
for(int i = ; i <= tot && i <= j; ++i)
{
while(j && !check(e[i].w, e[j].w)) --j;
int u = find(e[i].u), v = find(e[i].v);
if(u != v)
{
ans = min(ans, e[i].w + e[j].w);
d[u] = d[e[i].u] ^ d[e[i].v] ^ ;
fa[u] = v;
}
else if(d[e[i].u] == d[e[i].v])
{
ans = min(ans, e[i].w + e[j].w);
break;
}
}
printf("%d\n", ans);
return ;
}
bzoj4078的更多相关文章
- BZOJ4078 WF2014Metal Processing Plant(二分答案+2-SAT)
题面甚至没给范围,由数据可得n<=200.容易想到二分答案,暴力枚举某集合的价值,2-SATcheck一下即可.这样是O(n4logn)的. 2-SAT复杂度已经是下界,考虑如何优化枚举.稍微改 ...
- BZOJ4078 : [Wf2014]Metal Processing Plant
设$D(A)\leq D(B)$,从小到大枚举$D(A)$,双指针从大到小枚举$D(B)$. 那么对于权值不超过$D(A)$的边,可以忽略. 对于权值介于$(D(A),D(B)]$之间的边,需要满足那 ...
随机推荐
- 正则表达式提取String子串
最近遇到了一个字符串处理的功能,忽然发现了正则表达式的强大,深深的被她的迷人魅力所吸引,以前只是听说,今天亲眼所见,亲身经历,真的彻底折服. 言归正传:java中String类里面封装了很多字符串处理 ...
- IOS7 APP 升级的10个TIP 建议
There is no way to preserve the iOS 6 style status bar layout. The status bar will always overlap yo ...
- Python 之selenium+phantomJS斗鱼抓取案例
from selenium import webdriver from bs4 import BeautifulSoup import time if __name__ == '__main__': ...
- Ubuntu 18.04 安装chrome浏览器
参考 https://blog.csdn.net/cyem1/article/details/86297197 一分钟安装教程! 1.将下载源加入到系统的源列表(添加依赖) sudo wget htt ...
- Centos7自动式脚本搭建jumpserver
JumpServer脚本 这里需要安装阿里的yum源和epel源并解压: epel源地址https://mirrors.tuna.tsinghua.edu.cn/epel// 安装阿里互联网yum仓库 ...
- bootstrap table分页(前后端两种方式实现)
bootstrap table分页的两种方式: 前端分页:一次性从数据库查询所有的数据,在前端进行分页(数据量小的时候或者逻辑处理不复杂的话可以使用前端分页) 服务器分页:每次只查询当前页面加载所需要 ...
- Xcode 插件因为UUID原因不能使用解决办法
Xcode 经常因为一些原因不能使用,需要重新在 ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins目录下对每一个插件包下的p ...
- The C++ Programming Language - Bjarne Stroustrup
Preface Part 1: Introduction 1.1 The Structure of This Book 1.1.1 Introduction 1.1.2 Basic Facilitie ...
- Codeforces Round #427 (Div. 2)——ABCD
http://codeforces.com/contest/835 A.拼英语水平和手速的签到题 #include <bits/stdc++.h> using namespace std; ...
- bupt summer training for 16 #3 ——构造
https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 #include <cstdio> #include &l ...