您的位置:首页 > 其它

zoj 2008 单源最短路 SPFA

2014-03-21 00:06 316 查看
/*
题意:一个有向带权图,求1到所有点的最小权值,再求所有点到1的最小权值

题解:典型单源最短路,用SPFA实现,要求1分别为起点和终点时的最小权值和,
当1为终点时只需将图建立一个反向图,即可将终点当作起点计算
*/
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

#define Max 1000000001

using namespace std;

typedef struct
{
int pr;
int to;
}node;

int p;

vector<node> G[1000005],G0[1000005];
int dist[1000005];
bool vis[1000005];

void spfa(int start)
{
for(int i=0; i<=p; i++)
{
dist[i] = Max;
vis[i] = false;
}
queue<int> Q;
dist[start] = 0;
vis[start] = true;
Q.push(start);
while (!Q.empty())
{
int t = Q.front();
Q.pop();
for(int i=0; i<G[t].size(); i++)
{
if (dist[t]+G[t][i].pr < dist[G[t][i].to])
{
dist[G[t][i].to] = dist[t] + G[t][i].pr;
if (!vis[G[t][i].to])
{
Q.push(G[t][i].to);
vis[G[t][i].to] = true;
}
}
}
vis[t] = false;
}
}

void spfa0(int start)
{
for(int i=0; i<=p; i++)
{
dist[i] = Max;
vis[i] = false;
}
queue<int> Q;
dist[start] = 0;
vis[start] = true;
Q.push(start);
while (!Q.empty())
{
int t = Q.front();
Q.pop();
for(int i=0; i<G0[t].size(); i++)
{
if (dist[t]+G0[t][i].pr < dist[G0[t][i].to])
{
dist[G0[t][i].to] = dist[t] + G0[t][i].pr;
if (!vis[G0[t][i].to])
{
Q.push(G0[t][i].to);
vis[G0[t][i].to] = true;
}
}
}
vis[t] = false;
}
}

int main(void)
{
int n,q,fr,to,price;
cin >> n;
while (n--)
{
cin >> p >> q;
for(int i=0; i<=p; i++)
{
G[i].clear();
G0[i].clear();
}
while (q--)
{
cin >> fr >> to >> price;
node tmp;
tmp.to = to;
tmp.pr = price;
G[fr].push_back(tmp);
tmp.to = fr;
G0[to].push_back(tmp);
}
spfa(1);
int sum = 0;
for(int i=1; i<=p; i++)
sum += dist[i];
spfa0(1);
for(int i=1; i<=p; i++)
sum += dist[i];
cout << sum << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: