Codeforces Gym 101221G Metal Processing Plant(2-SAT)
题意:有 \(n\) 个元素,第 \(i\) 个数与第 \(j\) 个数之间有一个权值 \(d_{i,j}\),\(d(i,j)=d(j,i)\)。
定义函数 \(D(S)=\max\limits_{i \in S,j \in S,i \neq j}d(i,j)\)。
现在你要将 \(n\) 个元素划分为两个集合 \(A,B\),求 \(\min{D(A)+D(B)}\)。
\(1 \leq n \leq 200\)。
第一道 ACM World Final,祭一个。
看到这种非黑即白的问题,自然可以想到 2-SAT 啦。
很显然的思路是,不妨设 \(D(A)>D(B)\),枚举 \(D(A)\) 可能的值,二分 \(D(B)\) 的值,用 2-SAT 判定合法性,对于每个 \(d(i,j)>D(A)\),如果 \(i \in A\),那么 \(j \notin A\),\(D(B)\) 也同理。
不过这样是 \(n^4 \log n\) 的,因此需要优化。
我们将每个 \((i,j)\) 看做一条边,边权为 \(d(i,j)\),那么我们将边权从大到小排序,并顺次加边。
如果加入边权为 \(x\) 的边之后,图出现了奇数环,那么处理完 \(x\) 之后直接退出,因为我们无法对边权 \(\geq x\) 的进行黑白染色,使得同一条边两个端点颜色不同。
同理,如果加入边权为 \(x\) 的边之后,图出现了偶数环,那么这条边一定不能是 \(A\) 中边权最大的边。因为如果它是 \(A\) 中边权最大的边,那么它的两个端点颜色相同,可以看作一个点,偶数环变成了奇数环,显然是不满足条件的。
这样一来,我们最多只会加入 \(n-1\) 条树边,时间复杂度就降到了 \(n^3 \log n\) 了。
坑点:特判 \(n \leq 2\) 答案为 \(0\),我为此不停地 WA 3,然后发现 test 3 \(n=1\)?
//Coded by tzc_wk
/*
数据不清空,爆零两行泪。
多测不读完,爆零两行泪。
边界不特判,爆零两行泪。
贪心不证明,爆零两行泪。
D P 顺序错,爆零两行泪。
大小少等号,爆零两行泪。
变量不统一,爆零两行泪。
越界不判断,爆零两行泪。
调试不注释,爆零两行泪。
溢出不 l l,爆零两行泪。
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define giveup(...) return printf(__VA_ARGS__),0;
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define mask(a) (1ll<<(a))
#define maskx(a,x) ((a)<<(x))
#define _bit(a,x) (((a)>>(x))&1)
#define _sz(a) ((int)(a).size())
#define filei(a) freopen(a,"r",stdin);
#define fileo(a) freopen(a,"w",stdout);
#define fileio(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define put(x) putchar(x)
#define eoln put('\n')
#define space put(' ')
#define y1 y_chenxiaoyan_1
#define y0 y_chenxiaoyan_0
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
inline void print(int x){
if(x<0){
putchar('-');
print(abs(x));
return;
}
if(x<=9) putchar(x+'0');
else{
print(x/10);
putchar(x%10+'0');
}
}
inline int qpow(int x,int e,int _MOD){
int ans=1;
while(e){
if(e&1) ans=ans*x%_MOD;
x=x*x%_MOD;
e>>=1;
}
return ans;
}
struct edge{
int u,v,w;
edge(){/*ycxakioi*/}
edge(int _u,int _v,int _w){
u=_u;v=_v;w=_w;
}
friend bool operator <(edge a,edge b){
return a.w<b.w;
}
} e[40005];
int n=read(),cnt=0;
int f[405],col[405],siz[405];
inline int find(int x){
return (f[x]==x)?x:find(f[x]);
}
inline int getc(int x){
return (f[x]==x)?0:(getc(f[x])^col[x]);
}
vector<int> g[405];
int dfn[405],idx=0,low[405],stk[405],top,comp,bel[405],vis[405];
inline void tarjan(int x){
dfn[x]=low[x]=++idx;stk[++top]=x;vis[x]=1;
foreach(it,g[x]){
int y=*it;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(vis[y]){
low[x]=min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x]){
comp++;
while(top){
int y=stk[top--];
vis[y]=0;
bel[y]=comp;
if(y==x) break;
}
}
}
inline bool _2_SAT(int mn1,int mn2){
fill0(dfn);fill0(low);fill0(stk);fill0(vis);fill0(bel);
comp=top=idx=0;
fz(i,0,404) g[i].clear();
fz(i,1,cnt){
if(e[i].w>mn1) g[e[i].u*2-1].push_back(e[i].v*2),g[e[i].v*2-1].push_back(e[i].u*2);
if(e[i].w>mn2) g[e[i].u*2].push_back(e[i].v*2-1),g[e[i].v*2].push_back(e[i].u*2-1);
}
fz(i,1,n*2) if(!dfn[i]) tarjan(i);
fz(i,1,n) if(bel[i*2-1]==bel[i*2]) return 0;
return 1;
}
signed main(){
fz(i,1,n) fz(j,i+1,n){
int t=read();
e[++cnt].u=i;
e[cnt].v=j;
e[cnt].w=t;
}
if(n<=2) return puts("0"),0;
sort(e+1,e+cnt+1);
fz(i,1,n*2) f[i]=i,siz[i]=1;
int ans=INT_MAX;
fd(i,cnt,1){
int x=e[i].u,y=e[i].v,z=e[i].w;
int xx=find(x),yy=find(y);
if(xx!=yy){
if(siz[xx]<siz[yy]) swap(x,y),swap(xx,yy);
if(getc(x)==getc(y)) col[yy]^=1;
f[yy]=xx;
siz[xx]+=siz[yy];
}
else if(getc(x)!=getc(y)) continue;
int l=0,r=i-1,anss=0x3f3f3f3f;
while(l<=r){
int mid=(l+r)>>1;
if(_2_SAT(e[i].w,e[mid].w)) anss=e[mid].w,r=mid-1;
else l=mid+1;
}
ans=min(ans,e[i].w+anss);
if(getc(x)==getc(y)) break;
}
cout<<ans<<endl;
return 0;
}
Codeforces Gym 101221G 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 ...
- Codeforces A. Kyoya and Colored Balls(分步组合)
题目描述: Kyoya and Colored Balls time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- CodeFoeces GYM 101466A Gaby And Addition (字典树)
gym 101466A Gaby And Addition 题目分析 题意: 给出n个数,找任意两个数 “相加”,求这个结果的最大值和最小值,注意此处的加法为不进位加法. 思路: 由于给出的数最多有 ...
- Codeforces 733C:Epidemic in Monstropolis(暴力贪心)
http://codeforces.com/problemset/problem/733/C 题意:给出一个序列的怪兽体积 ai,怪兽只能吃相邻的怪兽,并且只有体积严格大于相邻的怪兽才能吃,吃完之后, ...
- Codeforces Round #249 (Div. 2)B(贪心法)
B. Pasha Maximizes time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces 1058 D. Vasya and Triangle(分解因子)
题目:http://codeforces.com/contest/1058/problem/D 题意:有一个大小为N*M的矩阵内,构造一个三角形,使面积为(n*m)/k.若存在输出三个顶点(整数). ...
- Gym 100712L Alternating Strings II(单调队列)
题目链接 Alternating Strings II 题意是指给出一个长度为n的01串,和一个整数k,要求将这个01串划分为很多子串(切很多刀),使得每个子串长度不超过k,且每个字串不是01交替出现 ...
- codeforces 816 E. Karen and Supermarket(树形dp)
题目链接:http://codeforces.com/contest/816/problem/E 题意:有n件商品,每件有价格ci,优惠券di,对于i>=2,使用di的条件为:xi的优惠券需要被 ...
- codeforces 807 D. Dynamic Problem Scoring(贪心+思维)
题目链接:http://codeforces.com/contest/807/problem/D 题意:对于动态计分的 Codeforces Round ,已知每题的 score 是根据 Round ...
随机推荐
- css单位px,em,rem区别
在css中单位长度用的最多的是px.em.rem,这三个的区别是: px是固定的像素,一旦设置了就无法因为适应页面大小而改变. em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定 ...
- SingnalR 从开发到生产部署闭坑指南
前天倒腾了一份[SignalR在react/go技术栈的实践], 步骤和思路大部分是外围框架的应用, 今天趁热打铁, 给一个我总结的SignalR避坑指南. 1.SignalR 默认协商 不管是.NE ...
- .Net Core微信服务商二次进件
最近商城进行微信服务商二次进件的开发,大致有几个点 一,服务商签名 二,服务商证书获取 三,图片上传 四,敏感信息加密 五,查询进件状态 除此之外,就是进件信息的拼装 电商二级商户进件申请单-状态流转 ...
- maven编码 gbk 的不可映射字符
解决这个问题的思路: 在maven的编译插件中声明正确的字符集编码编码--编译使用的字符集编码与代码文件使用的字符集编码一致!! 安装系统之后,一般中文系统默认字符集是GBK.我们安装的软件一般都继承 ...
- the Agiles Scrum Meeting 5
会议时间:2020.4.13 20:00 1.每个人的工作 今天已完成的工作 增量组:完成了增量开发的基础工作,初步完成了自动评测机制 issues:增量组:准备评测机制,增加仓库自动创建和管理 完善 ...
- 2021.8.6考试总结[NOIP模拟32]
T1 smooth 考场上水个了优先队列多带个$log$,前$80$分的点跑的飞快,后面直接萎了. 其实只需开$B$个队列,每次向对应队列中插入新的光滑数,就能保证队列中的数是单调的. 为了保证不重, ...
- FastAPI 学习之路(五十九)封装统一的json返回处理工具
这之前的接口,我们返回的格式都是每个接口异常返回的数据格式都会不一样,我们处理起来没有那么方便,我们可以封装一个统一的json处理. 那么我们看下如何来实现呢 from fastapi import ...
- 21.10.14 test
题目 WOJ5078 到 WOJ5081 T1 Problem A \(\color{green}{100}\) 由于每轮要选择尽量多的边删除,所以想到无向图的生成树,因为在生成树上再加一条边就会形成 ...
- 『学了就忘』Linux基础 — 16、Linux系统与Windows系统的不同
目录 1.Linux严格区分大小写 2.Linux一切皆文件 3.Linux不靠扩展名区分文件类型 4.Linux中所有的存储设备都必须在挂载之后才能使用 5.Windows下的程序不能直接在Linu ...
- docker创建本地主机实例Virtualbox 驱动出错
宿主机系统:Centos7 64位 创建主机实例Virtualbox 命令:docker-machine create -d virtualbox test 连接centos工具:Finalshell ...