本文出自:http://blog.csdn.net/svitter
题意:两个人从c出发,分别想去a,b旅行,两个城市之间只有一条路,有一个相应的价值。求最小的价值。通行的时候只花费一个价值。
本题目的关键在于优先队列,求出a, b, c到各点的最小价值,然后从中挑选一个点作为分开的点。
dijktra算法时用邻接表存储,因为明显是稀疏图。。还有就是存边的时候记得存双向的边,利用优先队列弹出最小的花费。使用邻接表记得初始化node[i] = -1(可以用memset)
AC:
//============================================================================ // Name : eee.cpp // Author : Vit // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define INF 0x1f1f1f1f struct str { int num; int cost; str(int n, int c): num(n), cost(c) {} str() {} friend bool operator < (str s1, str s2) { return s1.cost > s2.cost; } }; struct Arc { int next_arc; int point; int cost; }; Arc arc[20005]; //两个方向的边 int node[5005]; bool flag[5005]; int lowa[5005]; int lowb[5005]; int lowc[5005]; int m, n; int c, a ,b; void dijkstra(int src, int n, int *low)//low表示到每个点的最短距离 { memset(flag, 0, sizeof(flag)); priority_queue <str> q; q.push(str(src, 0)); int kk = 0; while(kk < n && !q.empty()) { str s = q.top(); q.pop(); if(flag[s.num]) continue; flag[s.num] = 1; low[s.num] = s.cost; kk++; for(int e = node[s.num]; e != -1; e=arc[e].next_arc) { if(!flag[arc[e].point]) { q.push(str(arc[e].point, arc[e].cost + s.cost)); } } } } void ace() { //work point int i, no = 1; int u, v, w; while(~scanf("%d%d", &n, &m)) { memset(node, -1, sizeof(node)); memset(lowa, 0x1f, sizeof(lowa)); memset(lowb, 0x1f, sizeof(lowb)); memset(lowc, 0x1f, sizeof(lowc)); scanf("%d%d%d", &a, &b, &c); for(i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); //头插法建立邻接表 arc[i].next_arc = node[u]; arc[i].point = v; arc[i].cost = w; node[u] = i; //反向边(本身无序) arc[m + i].next_arc = node[v]; arc[m + i].point = u; arc[m + i].cost = w; node[v] = m + i; } dijkstra(a, n, lowa); dijkstra(b, n, lowb); dijkstra(c, n, lowc); printf("Scenario #%d\n", no++); int res = INF; int sum; for(i = 1; i <= n; i++)//在i处分开 { sum = lowa[i] + lowb[i] + lowc[i]; if(sum < res) res = sum; } if(res >= INF) { printf("Can not reah!\n\n"); } else { printf("%d\n\n", res); } } } int main() { ace(); return 0; }
时间: 2024-09-30 06:32:48