1. 程式人生 > >【BZOJ1922】大陸爭霸

【BZOJ1922】大陸爭霸

題目連結:https://www.lydsy.com/JudgeOnline/problem.php?id=1922


 

漲姿勢了,,,這下不只是複習了。。。

此題可以認為是一種變相的最短路,嗯,有限制條件的最短路。

設dist1[i]表示到達某個結點的最短時間,dist2[i]表示可以進入某個結點的最短時間,顯然,真正進入的最短時間是max(dist1[i],dist2[i])。對於每一個用來更新其他結點的結點,我們用他實際進入的時間去更新與他相鄰的城市的到達時間,依賴於他的城市的可進入時間,並且依賴於他的城市的入度減1。每次更新都要把入度為0的點加入優先佇列,不管是原先就為0,還是減1後為0。

另外提一點,不要把讀入優化直接傳入引數,順序會變!別問我怎麼知道的。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5  
 6 using namespace std;
 7  
 8 inline int get_num() {
 9     int num = 0;
10     char c = getchar();
11     while (c < '0'
|| c > '9') c = getchar(); 12 while (c >= '0' && c <= '9') 13 num = num * 10 + c - '0', c = getchar(); 14 return num; 15 } 16 17 const int maxn = 3e3 + 5, maxm = 7e4 + 5, inf = 0x3f3f3f3f; 18 19 int head[maxn], eid, head2[maxn], eid2, ind[maxn]; 20 21 struct
Edge { 22 int v, w, next; 23 } edge[maxm], edge2[maxm]; 24 25 inline void insert(int u, int v, int w) { 26 edge[++eid].v = v; 27 edge[eid].w = w; 28 edge[eid].next = head[u]; 29 head[u] = eid; 30 } 31 32 inline void insert2(int u, int v) { 33 edge2[++eid2].v = v; 34 edge2[eid2].next = head2[u]; 35 head2[u] = eid2; 36 } 37 38 int dist1[maxn], dist2[maxn], vis[maxn]; 39 40 struct node { 41 int id, dist; 42 node(int id, int dist) : id(id), dist(dist) {} 43 bool operator < (const node& rhs) const { 44 return dist > rhs.dist; 45 } 46 }; 47 48 priority_queue<node> q; 49 50 inline void dijkstra() { 51 memset(dist1, inf, sizeof(dist1)); 52 dist1[1] = 0; 53 q.push(node(1, 0)); 54 while (!q.empty()) { 55 int u = q.top().id; 56 q.pop(); 57 if (vis[u]) continue; 58 vis[u] = 1; 59 int td = max(dist1[u], dist2[u]); 60 for (int p = head[u]; p; p = edge[p].next) { 61 int v = edge[p].v, w = edge[p].w; 62 if (dist1[v] > td + w) { 63 dist1[v] = td + w; 64 if (!ind[v]) q.push(node(v, max(dist1[v], dist2[v]))); 65 } 66 } 67 for (int p = head2[u]; p; p = edge2[p].next) { 68 int v = edge2[p].v; 69 --ind[v], dist2[v] = max(dist2[v], td); 70 if (!ind[v]) q.push(node(v, max(dist1[v], dist2[v]))); 71 } 72 } 73 } 74 75 int main() { 76 int n = get_num(), m = get_num(); 77 for (int i = 1; i <= m; ++i) { 78 int u = get_num(), v = get_num(), w = get_num(); 79 if (u != v) insert(u, v, w); 80 } 81 for (int i = 1; i <= n; ++i) { 82 ind[i] = get_num(); 83 for (int j = 1; j <= ind[i]; ++j) { 84 int x = get_num(); 85 insert2(x, i); 86 } 87 } 88 dijkstra(); 89 printf("%d", max(dist1[n], dist2[n])); 90 return 0; 91 }
AC程式碼