记录编号 |
371706 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[NOI 2014]魔法森林 |
最终得分 |
100 |
用户昵称 |
Cydiater |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
2.686 s |
提交时间 |
2017-02-16 18:53:14 |
内存使用 |
43.79 MiB |
显示代码纯文本
//BZOJ 3669
//by Cydiater
//2017.2.16
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
#include <string>
#include <iomanip>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <set>
#include <vector>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n) for(int (i)=(j);(i)<=(n);(i)++)
#define down(i,j,n) for(int (i)=(j);(i)>=(n);(i)--)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
#define FILE "magicalforest"
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,M,len=0,ans=oo;
struct edge{
int x,y,a,b;
}e[MAXN];
namespace LCT{
struct SplayTree{
int son[2],Max,val,fa,tag,id;
void clear(){son[0]=son[1]=Max=val=fa=0;}
}t[MAXN];
inline int isrt(int k){return t[k].fa==0||(t[t[k].fa].son[0]!=k&&t[t[k].fa].son[1]!=k);}
inline int get(int k){return t[t[k].fa].son[1]==k;}
inline void rev(int k){
if(!k)return;
swap(t[k].son[0],t[k].son[1]);
t[k].tag^=1;
}
inline void reload(int k){
if(!k)return;
t[k].Max=t[k].val;t[k].id=k;
int s1=t[k].son[0],s2=t[k].son[1];
if(t[s1].Max>t[k].Max){
t[k].Max=t[s1].Max;
t[k].id=t[s1].id;
}
if(t[s2].Max>t[k].Max){
t[k].Max=t[s2].Max;
t[k].id=t[s2].id;
}
}
inline void Pushdown(int k){
if(!k)return;
if(t[k].tag){
rev(t[k].son[0]);rev(t[k].son[1]);
t[k].tag^=1;
}
}
inline void rotate(int k){
int old=t[k].fa,oldf=t[old].fa,which=get(k);
if(!isrt(old))t[oldf].son[t[oldf].son[1]==old]=k;
t[old].son[which]=t[k].son[which^1];t[t[old].son[which]].fa=old;
t[k].son[which^1]=old;t[old].fa=k;t[k].fa=oldf;t[0].clear();
reload(old);reload(k);
}
int stack[MAXN],top=0;
inline void splay(int k){
top=0;stack[++top]=k;
for(int tmp=k;!isrt(tmp);tmp=t[tmp].fa){
stack[++top]=t[tmp].fa;
}
while(top)Pushdown(stack[top--]);
while(!isrt(k)){
int fa=t[k].fa;
if(!isrt(fa))rotate(get(fa)==get(k)?fa:k);
rotate(k);
}
}
inline void access(int k){
int tmp=0;
while(k){
splay(k);t[k].son[1]=tmp;
reload(k);tmp=k;k=t[k].fa;
}
}
void mrt(int k){
access(k);splay(k);rev(k);
}
int grt(int k){
access(k);splay(k);
while(t[k].son[0])k=t[k].son[0];
return k;
}
void Link(int x,int y){
mrt(x);t[x].fa=y;
}
void Cut(int x,int y){
mrt(x);access(y);splay(y);t[y].son[0]=t[x].fa=0;
reload(y);
}
int col(int x,int y){
mrt(x);access(y);splay(y);
return t[y].id;
}
}
int cnt;
namespace solution{
inline bool cmp(edge x,edge y){return x.a<y.a;}
void Prepare(){
N=read();M=read();
cnt=N;
up(i,1,M){
int x=read(),y=read(),a=read(),b=read();
e[++len]=(edge){x,y,a,b};
}
sort(e+1,e+M+1,cmp);
}
void Solve(){
up(i,1,M){
cnt++;
int x=e[i].x,y=e[i].y,a=e[i].a,b=e[i].b;
if(x==y)continue;
if(LCT::grt(x)!=LCT::grt(y)){
LCT::t[cnt].Max=b;
LCT::t[cnt].val=b;
LCT::t[cnt].id=cnt;
LCT::Link(x,cnt);
LCT::Link(cnt,y);
}
else{
int id=LCT::col(x,y);
if(LCT::t[id].val<=b)continue;
LCT::Cut(e[id-N].x,id);
LCT::Cut(e[id-N].y,id);
LCT::t[cnt].Max=b;
LCT::t[cnt].val=b;
LCT::t[cnt].id=cnt;
LCT::Link(x,cnt);
LCT::Link(cnt,y);
}
if(LCT::grt(1)==LCT::grt(N)){
int id=LCT::col(1,N);
cmin(ans,a+LCT::t[id].val);
}
}
if(ans==oo)ans=-1;
cout<<ans<<endl;
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
Prepare();
Solve();
return 0;
}