题意:链接
方法: LCT
解析:
水题。
两维的话根据经验第一维排序。
然后第二维直接维护最小生成树。
太水辣不知道该说些甚么。
因为写排序的cmp的时候手抖写成
if(a.a==b.b)return a.b
失去了1A的机会我的内心是崩溃的!
代码:
using namespace std;
int n,m,ans;
int val[K],ma[K],fa[K],ch[K][2],rt[K],rev[K];
int fffa[N];
struct node
{
int x,y,a,b,tag;
}edge[M];
int cmp(node a,node b)
{
if(a.a==b.a)return a.b<b.b;
return a.a<b.a;
}
void pushup(int x)
{
if(!x)return;
ma[x]=x;
if(ch[x][0]!=0&&val[ma[ch[x][0]]]>val[ma[x]])ma[x]=ma[ch[x][0]];
if(ch[x][1]!=0&&val[ma[ch[x][1]]]>val[ma[x]])ma[x]=ma[ch[x][1]];
}
void reverse(int x)
{
if(!x)return;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void pushdown(int x)
{
if(!x)return;
if(rev[x])
{
reverse(ch[x][0]);
reverse(ch[x][1]);
rev[x]^=1;
}
}
void down(int x)
{
if(!rt[x])down(fa[x]);
pushdown(x);
}
void rotate(int x)
{
int y=fa[x],kind=ch[y][1]==x;
ch[y][kind]=ch[x][!kind];
fa[ch[y][kind]]=y;
ch[x][!kind]=y;
fa[x]=fa[y];
fa[y]=x;
if(rt[y])rt[x]=1,rt[y]=0;
else ch[fa[x]][ch[fa[x]][1]==y]=x;
pushup(y);
}
void splay(int x)
{
down(x);
while(!rt[x])
{
int y=fa[x],z=fa[y];
if(rt[y])rotate(x);
else if((ch[y][1]==x)==(ch[z][1]==y))rotate(y),rotate(x);
else rotate(x),rotate(x);
}
pushup(x);
}
void access(int x)
{
int y=0;
while(x)
{
splay(x);
rt[ch[x][1]]=1,rt[y]=0;
ch[x][1]=y;
pushup(x);
y=x,x=fa[x];
}
}
void movetoroot(int x)
{
access(x);
splay(x);
reverse(x);
}
void link(int x,int y)
{
movetoroot(x);
fa[x]=y;
}
void cut(int x,int y)
{
movetoroot(x);
access(y);
splay(y);
ch[y][0]=0;
fa[x]=0;
rt[x]=1;
pushup(y);
}
int find_root(int x)
{
access(x),splay(x);
while(ch[x][0])x=ch[x][0];
return x;
}
int query(int x,int y)
{
if(find_root(x)!=find_root(y))return -1;
movetoroot(x);
access(y);
splay(y);
return ma[y];
}
void init()
{
for(int i=1;i<=n+m;i++)rt[i]=1,ma[i]=i;
}
int main()
{
ans=INF;
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&edge[i].x,&edge[i].y,&edge[i].a,&edge[i].b);
if(edge[i].x==edge[i].y)edge[i].tag=1;
}
sort(edge+1,edge+1+m,cmp);
int tot=0;
for(int i=1;i<=m;i++)
{
if(edge[i].tag==1)continue;
int x=edge[i].x,y=edge[i].y;
if(find_root(x)!=find_root(y))
{
val[i+n]=edge[i].b;
link(x,i+n),link(i+n,y);
}else
{
int t=query(x,y);
if(edge[i].b<val[t])
{
val[i+n]=edge[i].b;
cut(edge[t-n].x,t),cut(t,edge[t-n].y);
link(x,i+n),link(i+n,y);
}
}
int tmp=query(1,n);
if(tmp!=-1)
{
ans=min(ans,edge[i].a+val[tmp]);
}
}
if(ans==INF)printf("-1\n");
else printf("%d\n",ans);
}