BZOJ2069: [POI2004]ZAW
2069: [POI2004]ZAW
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 303 Solved: 138
[Submit][Status][Discuss]
Description
在
Byte山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是一条笔直通向“前面洞口”的道路.
隧道互相都不交叉(他们只在洞室相遇). 两个洞室要么就通过隧道连接起来,要么就经过若干隧道间接的相连.
现在决定组织办一个'King's of Byteotia Cup' 比赛. 参赛者的目标就是任意选择一条路径进入洞穴并尽快出来即可.
一条路径必须经过除了“前面洞口”之外还至少要经过其他一个洞室.一条路径中一个洞不能重复经过(除了“前面洞室”以外),类似的一条隧道也不能重复经
过.
一个著名的洞穴探险家 Byteala 正准备参加这个比赛. Byteala 已经训练了数月而且他已获得了洞穴系统的一套详细资料.
对于每条隧道他都详细计算了从两个方向经过所需要的时间. 经过一个洞室的时间很短可以忽略不记. 现在Byteala 向计算一条符合条件的最优路径.
Input
第一行有两个数n 和 m (3 <= n <=
5000, 3 <= m <= 10000) 分别表示洞室的数目以及连接他们的隧道的数目. 洞室从1 到 n编号.
“前面洞室”的编号为1. 接下来m 行描述了所有的隧道. 每行四个整数a,b,c,d
表示从洞室a到洞室b需要c分钟的时间,而从洞室b到洞室a需要d分钟的时间, 1 <= a,b <= n, a <> b,
1 <= c,d <= 10000. 你可以假设符合要求的路径肯定存在.
Output
输出一行,最少需要多少时间完成比赛.
Sample Input
3 3
1 2 4 3
2 3 4 2
1 3 1 1
1 2 4 3
2 3 4 2
1 3 1 1
Sample Output
6
HINT
【题解】
http://blog.csdn.net/popoqqq/article/details/46458079
OrzPoPoQQQ
犯的傻逼错:
1、优先队列比较写反
2、A->B却没有B->A
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 #include <vector> 7 #define max(a, b) ((a) > (b) ? (a) : (b)) 8 #define min(a, b) ((a) < (b) ? (a) : (b)) 9 10 inline void read(long long &x) 11 { 12 x = 0;char ch = getchar(), c = ch; 13 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 14 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 15 if(c == '-')x = -x; 16 } 17 18 const long long MAXN = 50000 + 100; 19 const long long MAXM = 100000 + 100; 20 const long long INF = 0x3f3f3f3f; 21 22 struct Edge 23 { 24 long long u,v,w,next; 25 Edge(long long _u, long long _v, long long _w, long long _next){u = _u;v = _v;w = _w;next = _next;} 26 Edge(){} 27 }edge[MAXM << 1]; 28 long long head[MAXN],cnt; 29 30 void insert(long long a, long long b, long long c) 31 { 32 edge[++cnt] = Edge(a,b,c,head[a]); 33 head[a] = cnt; 34 } 35 36 long long n,m,to1[MAXN],from1[MAXN],node[MAXN],tot; 37 38 long long A = 6000, B = 6001; 39 40 struct Node 41 { 42 long long v, d; 43 Node(long long _v, long long _d){v = _v;d = _d;} 44 Node(){} 45 }; 46 47 struct cmp 48 { 49 bool operator()(Node a, Node b) 50 { 51 return a.d > b.d; 52 } 53 }; 54 55 std::priority_queue<Node, std::vector<Node>, cmp> q; 56 57 long long d[MAXN], b[MAXN]; 58 59 void dijstra(long long s) 60 { 61 memset(b, 0, sizeof(b)); 62 memset(d, 0x3f, sizeof(d)); 63 while(q.size())q.pop(); 64 d[s] = 0; 65 q.push(Node(s, 0)); 66 Node now; 67 while(q.size()) 68 { 69 now = q.top(), q.pop(); 70 if(now.d != d[now.v] || b[now.v])continue; 71 b[now.v] = 1; 72 for(register long long pos = head[now.v];pos;pos = edge[pos].next) 73 { 74 long long v = edge[pos].v; 75 if(v > 6000 && v != A && v != B)continue; 76 if(b[v])continue; 77 if(d[now.v] + edge[pos].w < d[v]) 78 { 79 d[v] = d[now.v] + edge[pos].w; 80 q.push(Node(v, d[v])); 81 } 82 } 83 } 84 } 85 86 long long ans = INF; 87 88 int main() 89 { 90 read(n);read(m); 91 register long long tmp1, tmp2, tmp3, tmp4; 92 for(register long long i = 1;i <= m;++ i) 93 { 94 read(tmp1), read(tmp2), read(tmp3), read(tmp4); 95 if(tmp1 == 1) 96 { 97 node[++tot] = tmp2; 98 to1[tot] = tmp4; 99 from1[tot] = tmp3; 100 continue; 101 } 102 else if(tmp2 == 1) 103 { 104 node[++tot] = tmp1; 105 to1[tot] = tmp3; 106 from1[tot] = tmp4; 107 continue; 108 } 109 insert(tmp1, tmp2, tmp3); 110 insert(tmp2, tmp1, tmp4); 111 } 112 long long M = 0; 113 while((1 << M) <= n) ++ M; 114 -- M; 115 for(register long long i = 0;i <= M;++ i) 116 { 117 for(register long long j = 1;j <= tot;++ j) 118 { 119 if((node[j] >> i) & 1) 120 insert(A, node[j], from1[j]); 121 else 122 insert(node[j], B, to1[j]); 123 } 124 dijstra(A); 125 ans = min(ans, d[B]); 126 A = B + 1; 127 B = B + 2; 128 for(register long long j = 1;j <= tot;++ j) 129 { 130 if((node[j] >> i) & 1) 131 insert(node[j], A, to1[j]); 132 else 133 insert(B, node[j], from1[j]); 134 } 135 dijstra(B); 136 ans = min(ans, d[A]); 137 A = B + 1; 138 B = B + 2; 139 } 140 printf("%d", ans); 141 return 0; 142 }