题解:
我们枚举最大边,然后再二分第二大边即可。
注意到加入最大边后如果和不能选的比他大的边形成了偶环,那么一定有一个之前的出现过,我们可以跳过对他的判断。 如果是奇环就一定会出现一条,这时后面的都不用判断了。
时间复杂度
。
#include <bits/stdc++.h>
using namespace std;
typedef pair <int,int> pii;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=4e2+50;
int n,m,anc[N],val[N],ans=0x3f3f3f3f;
struct E {
int x,y,w;
E() {}
E(int x,int y,int w) : x(x), y(y), w(w) {}
friend inline bool operator <(const E &a,const E &b) {return a.w<b.w;}
} e[N*N];
inline pii ga(int x) {
if(x==anc[x]) return pii(x,0);
pii f=ga(anc[x]);
val[x]=val[x]^f.second;
anc[x]=f.first;
return pii(anc[x],val[x]);
}
map <int,int> S;
vector <int> edge[N];
int dfn[N],bl[N],st[N],low[N],ins[N],top,ind,scc;
inline void dfs(int x) {
dfn[x]=low[x]=++ind; ins[st[++top]=x]=1;
for(int e=edge[x].size()-1;e>=0;e--) {
int v=edge[x][e];
if(!dfn[v]) dfs(v), low[x]=min(low[x],low[v]);
else if(ins[v]) low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x]) {
++scc;
int u; do {
u=st[top--];
ins[u]=0;
bl[u]=scc;
} while(u!=x);
}
}
inline bool check(int lim1,int lim2) {
for(int i=1;i<=2*n;i++) edge[i].clear();
memset(dfn,0,sizeof(dfn)); ind=scc=0;
for(int i=1;i<=m;i++) {
if(e[i].w>lim1) {
edge[e[i].x*2-1].push_back(e[i].y*2);
edge[e[i].y*2-1].push_back(e[i].x*2);
}
if(e[i].w>lim2) {
edge[e[i].x*2].push_back(e[i].y*2-1);
edge[e[i].y*2].push_back(e[i].x*2-1);
}
}
for(int i=1;i<=2*n;i++) if(!dfn[i]) dfs(i);
for(int i=1;i<=n;i++) if(bl[i*2]==bl[i*2-1]) return false;
return true;
}
inline void calc(int A) {
if(S[A]) return; S[A]=1;
int l=0,r=A;
while(l<=r) {
int mid=(l+r)>>1;
if(check(A,mid)) {ans=min(ans,mid+A); r=mid-1;}
else l=mid+1;
}
}
int main() {
n=rd();
for(int i=1;i<=n;i++) anc[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
e[++m]=E(i,j,rd());
sort(e+1,e+m+1);
for(int i=m;i>=1;i--) {
int x=e[i].x, y=e[i].y;
pii xx=ga(x), yy=ga(y);
if(xx.first==yy.first) {
if(xx.second!=yy.second) continue;
else {calc(e[i].w); break;}
} calc(e[i].w);
anc[xx.first]=yy.first;
val[xx.first]=xx.second^yy.second^1;
} calc(0); cout<<ans<<'\n';
}