对于这道题的解法,感觉是部分暴力,枚举带几只A型守护精灵,就可以将这道题转化成求类似于bzoj2594了。
参考题解:
http://wenku.baidu.com/view/a611cec4dd3383c4bb4cd2d8.html
http://www.cnblogs.com/JoeFan/p/4451249.html
找错时深刻体会到老师讲的静态测试能找出一半的错。
(昨天把手机电池摔坏了,借别人的手机定闹钟,结果因为重新开了下机,手机时间12点左右,正常时间11点左右,所以造成定的6点多的闹钟,抬头看外面黑暗暗的,就决定继续睡,还想着,今天太累了,实在起不来,结果后来发现真相的我眼泪掉下来)
#include
#include
#include
#include
using namespace std;
#define N 50010
#define M 100010
#define INF 0x3f3f3f3f
struct node{
node *fa;
node *ch[2];
int rev;
int val;
int valnum;
int maxval;
int maxvalnum;
int from;
int to;
void init(int tempval,int tempvalnum,int tempfrom,int tempto){
ch[0]=ch[1]=fa=NULL;
rev=0;
val=tempval;
valnum=tempvalnum;
maxval=val;
maxvalnum=valnum;
from=tempfrom;
to=tempto;
}
bool isroot(){
return fa==NULL||(fa->ch[0]!=this&&fa->ch[1]!=this);
}
void fswitch(){
rev^=1;
swap(ch[0],ch[1]);
return;
}
void push_down(){
if(rev){
if(ch[0]){
ch[0]->fswitch();
}
if(ch[1]){
ch[1]->fswitch();
}
rev=0;
}
return;
}
void go(){
if(!isroot()){
fa->go();
}
push_down();
return;
}
int dir(){
return fa->ch[1]==this?1:0;
}
void setedge(int d,node *another){
ch[d]=another;
if(another){
another->fa=this;
}
return;
}
void push_up(){
maxval=val;
maxvalnum=valnum;
if(ch[0]){
if(maxvalnummaxvalnum){
maxvalnum=ch[0]->maxvalnum;
maxval=ch[0]->maxval;
}
}
if(ch[1]){
if(maxvalnummaxvalnum){
maxvalnum=ch[1]->maxvalnum;
maxval=ch[1]->maxval;
}
}
return;
}
void rot(){
int d=dir();
node *tempfafa=fa->fa;
if(!(fa->isroot())){
tempfafa->ch[fa->dir()]=this;
}
fa->setedge(d,ch[!d]);
setedge(!d,fa);
fa=tempfafa;
ch[!d]->push_up();
return;
}
void splay(){
go();
while(!isroot()){
if(!(fa->isroot())){
dir()==fa->dir()?fa->rot():rot();
}
rot();
}
push_up();
return;
}
void access(){
for(node *p=this,*q=NULL;p;q=p,p=p->fa){
p->splay();
p->setedge(1,q);
p->push_up();
}
splay();
return;
}
void make_root(){
access();
fswitch();
return;
}
void cut(node *another){
another->make_root();
access();
ch[0]->fa=NULL;
ch[0]=NULL;
push_up();
return;
}
void link(node *another){
another->make_root();
another->fa=this;
return;
}
node *find_root(){
node *temp=this;
while(temp->fa){
temp=temp->fa;
}
return temp;
}
bool islink(node *another){
return find_root()==another->find_root()?true:false;
}
int querymax(node *another){
another->make_root();
access();
return maxval;
}
};
struct edge{
int from,to;
int ai,bi;
};
bool cmp(edge a,edge b){
return a.aiislink(tree[y])){
int temp=tree[x]->querymax(tree[y]);
if(tree[temp]->valnum>w){//把w写成了x,wr了,强调:想着意义写代码,每个代码都是一段故事(文艺版)
tree[temp]->cut(tree[tree[temp]->from]);
tree[temp]->cut(tree[tree[temp]->to]);
tree[temp]->init(temp,w,x,y);
tree[temp]->link(tree[y]);
tree[temp]->link(tree[x]);
}
}
else{
tree[++cou]=&(pool[cou]);
tree[cou]->init(cou,w,x,y);
tree[cou]->link(tree[x]);
tree[cou]->link(tree[y]);
}
return;
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
if(m==0){
//printf("wo shi da hao ren");
printf("-1\n");
}
else{
for(int i=1;i<=n;i++){
tree[i]=&(pool[i]);
tree[i]->init(i,-1,-1,-1);
}
cou=n;
for(int i=0;iislink(tree[n])){
int temp=tree[1]->querymax(tree[n]);
if(nowai+tree[temp]->valnumvalnum;
}
}
nowai=edgearray[i].ai;
}
addedge(edgearray[i].from,edgearray[i].to,edgearray[i].bi);
}
if(tree[1]->islink(tree[n])){
int temp=tree[1]->querymax(tree[n]);
if(edgearray[m-1].ai+tree[temp]->valnumvalnum;
}
}
if(ans==INF){
printf("-1\n");
}
else{
printf("%d\n",ans);
}
}
return 0;
}