本文出自: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;
}