好朋友
noip2011就要来了,W校的同学们不仅看重这次比赛,更看重noip2011和谁住在同一个房间。同学之间的关系好坏可以用一个亲密值表示,亲密值越大,两个同学关系越好。小A作为W校信息组的组长,自然想要让同学们在比赛前能好好休息,放松心情,让同学们在赛场上能够超常发挥。他现在知道自己预订的房间都是双人间,且知道这n个同学之间的关系。n个同学的关系可以用一个n条双向边的连通图来描述,即某个同学只愿意和与他有边相连的同学住同一个房间,边权即为两个同学的亲密值。数据保证没有重边、自环。现在小A想知道在让所有同学的要求满足的情况下,亲密值最低的一对同学亲密值最高是多少。
输入格式:
第一行一个正整数n,下面n行每行三个数u,v,w,表示u到v有一条边权为w的双向边。
输出格式:
假如无论如何都无法满足所有同学的要求,输出”no answer”,否则输出亲密值最低的一对同学的最高亲密值。
样例输入:
4 1 2 3 2 3 10 3 4 3 1 4 1
样例输出:
3
数据范围:
50%的数据满足n<=20;
80%的数据满足n<=1000;
100%的数据满足n<=100000,-10^9<=w<=10^9
时间限制:
1S
空间限制:
64M
提示:
remove!!!
复杂度(O(n))
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using
namespace
std;
#define N 400001
#define PER(i,a,b) for(int i=a;i<=b;i++)
bool
pg[N];
int
t[N];
int
val[N];
int
fi[N],cis;
int
ond,sed;
int
q[2*N];
int
d[N],ne[N],cir[N],civ[N];
int
n,l,tot,ans=2e9,u,v,w,he,ta,onen;
void
s(){
puts
(
"no answer"
);
exit
(0);}
void
add(
int
u,
int
v,
int
w){t[++tot]=v;val[tot]=w;ne[tot]=fi[u];fi[u]=tot;}
void
init(){
scanf
(
"%d"
,&n);PER(i,1,n) {
scanf
(
"%d%d%d"
,&u,&v,&w),add(u,v,w),add(v,u,w),d[u]++,d[v]++;}
if
(n%2) s();}
void
dfs(
int
x,
int
nownum)
{
if
(pg[x])
return
;
cis=nownum;cir[nownum]=x;pg[x]=1;
for
(
int
i=fi[x];i;i=ne[i]){
if
(!pg[t[i]]){dfs(t[i],nownum+1);civ[nownum]=val[i];
break
;}}
return
;
}
int
main()
{
init();he=ta=0;PER(i,1,n){
if
(d[i]==1) q[++ta]=i;
else
if
(d[i]==0) s();}
while
(he++<ta)
{
if
(pg[q[he]])
continue
;
l=0;
for
(
int
i=fi[q[he]];i;i=ne[i])
{
if
(!pg[t[i]]){l=t[i];pg[t[i]]=pg[q[he]]=1;ans=min(ans,val[i]);
break
;}
}
if
(!l)s();
for
(
int
i=fi[l];i;i=ne[i])
{
if
(!pg[t[i]])
{
if
(--d[t[i]]==1) q[++ta]=t[i];
else
if
(!d[t[i]]) s();
}
}
}
bool
flag=0;
PER(i,1,n)
if
(!pg[i]){ onen=i;flag=1;
break
;}
if
(!flag) {cout<<ans;
return
0;}
dfs(onen,1);
for
(
int
i=fi[cir[cis]];i;i=ne[i])
{
if
(t[i]==cir[1]) {civ[0]=val[i];
break
;}
}
sed=ond=ans;PER(i,1,cis/2){ond=min(ond,civ[i*2-1]);sed=min(sed,civ[i*2-2]);}
ans=max(sed,ond);
cout<<ans;
}