n<=50000,m<=100000的圖上,路徑有屬性ai和bi,問從1到n的路徑中(ai的最大值+bi的最大值)的最小值。
雙屬性圖論題,常用套路--定一動二。比如說這裡可以先按a從小到大排序,然後依次加入圖中來考慮怎麼計算b。
方法一:哦,最大值最小,那不是最小生成樹嗎?會加邊的圖,那不是lct維護最小生成樹嗎?
1view code//#include
2 #include3 #include4
//#include5//
#include6//
#include7//
#include8//
#include9//
#include
10 #include11 #include12
using
namespace
std;
1314
#define ll long long
15ll qread()
1620
21//
pay attention to '-' , ll and double of qread!!!!
2223
intn,m;
24#define maxn 150011
25struct
lct26
a[maxn];
28int
n;29
void clear(int n)
30void up(int
x)31
35else
if (c.max>=b.v && c.max>=d.max)
36else 37}
38void revsingle(int x)
39void down(int x) }
40bool isroot(int x)
41void rotate(int
x)42
53int
sta[maxn],top;
54void download(int
x)55
59void splay(int
x)60
67rotate(x);68}
69up(x);70}
71void access(int x) splay(z);}
72void reset(int
x) 73
74void link(int x,int y)
75void cut(int x,int
y)76
77bool con(int x,int y) return0;}
78int qmax(int x,int y)
7980
//void test()
81//
85}t;
8687
struct ee }ee[maxn];
88int
main()
8992 sort(ee+1,ee+1+m);
9394
int ans=0x3f3f3f3f
;95 t.clear(n+m);
96for (int i=1;i<=n;i++) t.a[i].v=-0x3f3f3f3f,t.a[i].max=-0x3f3f3f3f,t.a[i].maxid=i;
97for (int i=n+1;i<=n+m;i++) t.a[i].v=ee[i-n].b,t.a[i].max=t.a[i].v,t.a[i].maxid=i;
98for (int i=1;i<=m;i++)
99110
}111
else
112if (t.con(1,n)) ans=min(ans,ee[i].a+t.a[t.qmax(1
,n)].v);
113}
114 printf("
%d\n
",ans==0x3f3f3f3f?-1
:ans);
115return0;
116 }
好久沒寫了,這次寫起來居然這麼順這麼短,有點屌。
方法二:lct學傻了系列,可以先考慮乙個暴力:每次加完邊之後做一次最短路。不過加了一條邊之後,所有導致每個點的答案被更新的根本原因,來自於這條邊兩端的點的互相更新。也就是說,每加一條邊後,前面圖的大部分資訊是不用算的,就看一下這條邊兩端的點能否更新彼此,能的話把被更新的點加入佇列再跑最短路就ok。複雜度??玄學,反正比lct快,好寫!
1 #includeview code2 #include3 #include4 #include5
//#include
6 #include7 #include8
//#include9//
#include
10using
namespace
std;
1112
intn,m;
13#define maxn 200011
14#define maxm 200011
15struct listlist[maxm];
16bool cmpa(const list &a,const list &b)
17struct edgeedge[maxm]; int first[maxn],le=2;18
void
in(int x,int y,int v)
19void insert(int x,int y,int v)
2021
struct
qnode
2225
};26 priority_queue,greater>q;
27int
dis[maxn];
2829
void kick(int x,int y,int
ev)30
);35}36
}37void
dijkstra()
38);50}
51}52}
53}5455
intmain()
5671
dijkstra();
72 ans=min(ans,list[i].a+dis[n]);73}
74if (ans==0x3f3f3f3f) puts("-1"
);75
else printf("
%d\n
",ans);
76return0;
77 }
bzoj3669 NOI2014 魔法森林
給定n個點m條邊的無向圖,每條邊有兩個權值a與b。求一條1到n的路徑使得路徑經過邊的最大a與最大b的和最小。無法到達輸出 1。n 50000,m 100000。我們嘗試列舉路徑的最大a值,那麼我們只需按照a排序按順序插入,維護1到n的b最大值即可。用並查集維護連通性。當加入j到k這條邊時如果形成環,...
bzoj 3669 Noi2014 魔法森林
description 為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在1號節點,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有...
bzoj 3669 NOI2014 魔法森林
為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在號節點1,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有人經過一條邊的時候,這條...