【NOI2014】魔法森林

题面太鬼,这是链接

首先,此题正解LCT。。。。。。先%%%一发,不会LCT

然后玄学解法是Superfast。。。

把边按A守护精灵升序,用Superfast记录仪B守护精灵

然后不断加边,每加一条边就松弛两个端点然后记录答案(答案==这条边A守护精灵数量(因为是最大的)+1~n的最短距离(距离是B守护精灵数)),然后加完边答案就统计出来了。。。

然后就能AC此题。。。。。。。。。。。。。。。。。

算法正确性的证明:不会

 1 // It is made by XZZ
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
 7 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
 8 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
 9 #define il inline
10 #define rg register
11 #define vd void
12 #define t (dis[i])
13 typedef long long ll;
14 il int gi(){
15     rg int x=0;rg char ch=getchar();
16     while(ch<'0'||ch>'9')ch=getchar();
17     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
18     return x;
19 }
20 #define X E[i].x
21 #define Y E[i].y
22 #define A E[i].a
23 #define B E[i].b
24 #define inf 123456
25 struct edge{int x,y,a,b;}E[100001];
26 bool operator < (edge a,edge b){return a.a<b.a;}
27 const int maxn=50002,maxm=200011;
28 int fir[maxn],dis[maxm],nxt[maxm],a[maxm],b[maxm],id=0;
29 il vd add(int fr,int to,int aa,int bb){
30     nxt[++id]=fir[fr],fir[fr]=id,dis[id]=to,a[id]=aa,b[id]=bb;
31 }
32 queue<int>que;bool inque[maxn]={0}; 
33 int Dis[maxn],n;
34 il int spfa(){
35     while(!que.empty()){
36         int now=que.front();
37         erep(i,now)
38             if(Dis[t]>max(Dis[now],b[i])){
39                 Dis[t]=max(Dis[now],b[i]);
40                 if(!inque[t])que.push(t),inque[t]=1; 
41             }
42         que.pop(),inque[now]=0;
43     }return Dis[n];
44 }
45 int main(){
46     n=gi();
47     rg int m=gi(),ans=inf;
48     rep(i,1,m)X=gi(),Y=gi(),A=gi(),B=gi();
49     sort(E+1,E+m+1);
50     rep(i,2,n)Dis[i]=inf;
51     rep(i,1,m)
52         add(X,Y,A,B),add(Y,X,A,B),
53         que.push(X),que.push(Y),
54         inque[X]=inque[Y]=1,ans=min(ans,spfa()+A);
55     if(ans==inf)puts("-1");
56     else printf("%d
",ans); 
57     return 0;
58 }
View Code
原文地址:https://www.cnblogs.com/xzz_233/p/7217004.html