您的位置:首页 > 其它

最短路(Dijkstra) HDOJ 4318 Power transmission

2015-08-24 14:48 211 查看
题目传送门

题意:起点s到终点t送电,中途会有损耗,问最小损耗是多少

分析:可以转换为单源最短路问题,用优先队列的Dijkstra版本,d[]表示从s出发到当前点的最小损耗,用res保存剩下的电量。当到达t就结束,因为按照w从小到大排序,访问过的点都已经最优,这是贪心思想

收获:复习了Dijkstra,进一步理解Dijkstra的贪心的思想(程序跑得慢,还可优化)

代码:

/************************************************
* Author        :Running_Time
* Created Time  :2015-8-24 9:51:51
* File Name     :I.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
typedef pair<int, int> P;
const int N = 5e4 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
struct Edge	{
int v;
double w, res;
bool operator < (const Edge &r)	const {
return w > r.w;
}
};
vector<Edge> G
;
bool vis
;
double d
;
int n, s, t;
double M;

void Dijkstra(void)	{
priority_queue<Edge> Q;
memset (vis, false, sizeof (vis));
for (int i=1; i<=n; ++i)	d[i] = INF;
d[s] = 0;	Q.push ((Edge) {s, 0, M});
while (!Q.empty ())	{
Edge r = Q.top ();	Q.pop ();
int u = r.v; double res = r.res;
if (vis[u]) continue;
vis[u] = true;
if (u == t)	{
printf ("%.2f\n", M - res);	return ;
}
for (int i=0; i<G[u].size (); ++i)	{
int v = G[u][i].v;	double w = G[u][i].w;
if (!vis[v] && d[v] > d[u] + res * w)	{
d[v] = d[u] + res * w;
Q.push ((Edge) {v, d[v], res - res * w});
}
}
}

puts ("IMPOSSIBLE!");
}

int main(void)    {
while (scanf ("%d", &n) == 1)	{
for (int i=1; i<=n; ++i)	{
G[i].clear ();
int k;	scanf ("%d", &k);
for (int j=1; j<=k; ++j)	{
int v;	double w;	scanf ("%d%lf", &v, &w);	w /= 100;
G[i].push_back ((Edge) {v, w});
}
}
scanf ("%d%d%lf", &s, &t, &M);
Dijkstra ();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: