菩萨为行,福慧双修,智人得果,不忘其本。
——唐朠立《大慈恩寺三藏法师传》
有才而知进退,福慧双修,这才难得。
——乌雅氏
如何福慧双修?被太后教导的甄嬛徘徊在御花园当中。突然,她发现御花园中的花朵全都是红色和蓝色的。她冥冥之中得到了响应:这就是指导她如何福慧双修的! 现在御花园可以看作是有N块区域,M条小路,两块区域之间可通过小路连接起来。现在甄嬛站在1号区域,而她需要在御花园中绕一绕,且至少经过1个非1号区 域的区域。但是恰好1号区域离碎玉轩最近,因此她最后还是要回到1号区域。由于太后教导她要福慧双修,因此,甄嬛不能走过任何一条她曾经走过的路。但是, 御花园中来往的奴才们太多了,而且奴才们前行的方向也不一样,因此甄嬛在走某条小路的时候,方向不同所花的时间不一定一样。天色快暗了,甄嬛需要尽快知道 至少需要花多少时间才能学会如何福慧双修。如果甄嬛无法达到目的,输出“-1”。
第一行仅2个正整数n,m,意义如题。
接下来m行每行4个正整数s,t,v,w,其中s,t为小路所连接的两个区域的编号,v为甄嬛从s到t所需的时间,w为甄嬛从t到s所需的时间。数据保证无重边。
仅一行,为甄嬛回到1号区域所需的最短时间,若方案不存在,则输出-1
HINT
[样例解释]
对于第一个数据:路径为1->2->3->1,所需时间为8,而1->3->2->1所花时间为9。因此答案为8.
[数据范围与约定]
对于40%的数据:n<=1,000; m<=5,000
对于100%的数据:1<=n<=40,000; 1<=m<=100,000; 1<=v,w<=1,000
1 #include<bits/stdc++.h>
2 const int maxn = 40035;
3 const int maxm = 200035;
4
5 struct Edge
6 {
7 int v,c;
8 Edge(int a=0, int b=0):v(a),c(b) {}
9 }edges[maxm];
10 struct node
11 {
12 int x,d;
13 node(int a=0, int b=0):x(a),d(b) {}
14 bool operator < (node a) const
15 {
16 return d > a.d;
17 }
18 };
19 int n,m,ans,dis[maxn],dfn[maxn],tim;
20 int edgeTot,head[maxn],nxt[maxm],tag[maxm];
21 std::priority_queue<node> q;
22
23 int read()
24 {
25 char ch = getchar();
26 int num = 0, fl = 1;
27 for (; !isdigit(ch); ch=getchar())
28 if (ch==‘-‘) fl = -1;
29 for (; isdigit(ch); ch=getchar())
30 num = (num<<1)+(num<<3)+ch-48;
31 return num*fl;
32 }
33 void addedge(int u, int v, int c)
34 {
36 edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
37 }
38 void dijkstra()
39 {
40 memset(dis, 0x3f3f3f3f, sizeof dis);
41 ++tim, q.push(node(1, 0)), dis[1] = 0;
42 for (node tmp; q.size(); )
43 {
44 tmp = q.top(), q.pop();
45 if (dfn[tmp.x]==tim) continue;
46 dfn[tmp.x] = tim;
47 for (int i=head[tmp.x]; i!=-1; i=nxt[i])
48 if (tag[i]!=-1)
49 {
50 int v = edges[i].v;
51 if (dis[v] > dis[tmp.x]+edges[i].c)
52 dis[v] = dis[tmp.x]+edges[i].c, q.push(node(v, dis[v]));
53 }
54 }
56 for (int i=head[1]; i!=-1; i=nxt[i])
57 if (tag[i]==-1&&(ans==-1||(ans > dis[edges[i].v]+edges[i^1].c)))
58 ans = dis[edges[i].v]+edges[i^1].c;
59 }
60 int main()
61 {
62 memset(head, -1, sizeof head);
63 n = read(), m = read(), ans = edgeTot = -1;
64 for (int i=1; i<=m; i++)
65 {
66 int u = read(), v = read(), s = read(), t = read();
67 addedge(u, v, s), addedge(v, u, t);
68 }
69 for (int d=18; d>=0; --d)
70 {
71 for (int i=head[1]; i!=-1; i=nxt[i])
72 if ((i>>d)&1) tag[i] = 0, tag[i^1] = -1;
73 else tag[i] = -1, tag[i^1] = 0;
74 dijkstra();
75 for (int i=head[1]; i!=-1; i=nxt[i])
76 if ((i>>d)&1) tag[i] = -1, tag[i^1] = 0;
77 else tag[i] = 0, tag[i^1] = -1;
78 dijkstra();
79 }
80 printf("%d\n",ans);
81 return 0;
82 }