【日常训练】Volleyball(CodeForces-96D)

题意与分析

这题也是傻逼题,可是我当时打比赛的时候板子出问题了- -|||,怎么调也调不过。

不过思路是很清晰的:先做n次dijkstra然后重新建图,建完了以后根据新的单向图再跑一次dijkstra。

代码

 1 #include <bits/stdc++.h>
 2 
 3 #define ZERO(x) memset(x, 0, sizeof(x))
 4 using namespace std;
 5 using ll=long long;
 6 
 7 struct Edge { int v, nxt; ll c; };
 8 Edge w[20005];
 9 vector<int>    que;
10 ll dist[1005], a[1005], b[1005];
11 int    e[1005][1005], ww[1005];
12 bool vis[1005];
13 int    N, M, x, y, W = 1;
14 
15 void ShortestPath(int s)
16 {
17     memset(dist, 60, sizeof(dist)); dist[s] = 0;
18     ZERO(vis); vis[s]=true;
19     que.clear();
20     que.push_back(s);
21     for (int fi = 0; fi < que.size(); ++ fi)
22     {
23         int    u = que[fi];
24         for (int i = ww[u]; i; i = w[i].nxt)
25         {
26             int    v = w[i].v;
27             if (dist[v] <= dist[u] + w[i].c) continue;
28             dist[v] = dist[u] + w[i].c;
29             if (vis[v]) continue;
30             vis[v] = true;
31             que.push_back(v);
32         }
33         vis[u] = false;
34     }
35     
36     e[s][0] = 0;
37     for (int i = 1; i <= N; ++ i)
38         if (i != s && dist[i] <= a[s]) e[s][++ e[s][0]] = i;
39 }
40 
41 
42 int    main()
43 {
44     cin >> N >> M;
45     cin >> x >> y;
46     for (int i = 1, u, v; i <= M; ++ i)
47     {
48         ll    c;
49         cin >> u >> v >> c;
50         w[++ W].v = v; w[W].c = c; w[W].nxt = ww[u]; ww[u] = W;
51         w[++ W].v = u; w[W].c = c; w[W].nxt = ww[v]; ww[v] = W;
52     }
53     for (int i = 1; i <= N; ++ i) cin >> a[i] >> b[i];
54     for (int i = 1; i <= N; ++ i) ShortestPath(i);
55     
56     memset(dist, 60, sizeof(dist)); dist[x] = 0;
57     ZERO(vis); vis[x]=true;
58     que.clear();
59     que.push_back(x);
60     for (int fi = 0; fi < que.size(); ++ fi)
61     {
62         int    u = que[fi];
63         for (int i = 1; i <= e[u][0]; ++ i)
64         {
65             int    v = e[u][i];
66             if (dist[v] <= dist[u] + b[u]) continue;
67             dist[v] = dist[u] + b[u];
68             if (vis[v]) continue;
69             vis[v] = 1;
70             que.push_back(v);
71         }
72         vis[u] = 0;
73     }
74     
75     if (dist[y] > (1ll << 60)) dist[y] = -1;
76     cout << dist[y] << endl;
77         
78     return 0;
79 }
点我看时雨色图

 

posted @ 2019-03-16 15:43  ISoLT  阅读(138)  评论(0编辑  收藏  举报