您的位置:首页 > 其它

poj 1511 Invitation Cards spfa 邻接矩阵

2015-01-17 12:10 253 查看
题目链接:

  http://poj.org/problem?id=1511

题目大意:

  这道题目比较难理解,我读了好长时间,最后还是在队友的帮助下理解了题意,大意就是,以一为起点,求从一到其他各点的最短回路总和。

解题思路:

  解决这个题目有几个容易错的,解决了离ac就不远了^_^。

  1:数据范围是1<=边数<=顶点数<=1000000,所以不能用邻接矩阵,要用邻接表,用vector实现时要动态申请内存。

  2:求得是起始点到其他点的最短回路和,我们可以建两个邻接表(一个正向,一个负向邻接表),对两个表分别spfa就可以了。

  3:数据太大,最后结果要用__int64或者long long保存。

(这是第一次写spfa,也是第一次用vector实现邻接表,在队友的帮助下一直从大早上到现在终于解决了,可以松口气去吃饭了)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 1000005
#define INF 2000000000

struct Egde
{
int e, w;
Egde(int e=0, int w=0) : e(e),w(w) {};//构造函数,初始化
};
bool vis[maxn];
__int64 dist[maxn], p;
vector< vector<Egde> >G[2];

void init ()
{
int i;
for (i=0; i<=p; i++)
dist[i] = INF;
}
void spfa (int x, int s);

int main ()
{
int t, q;
scanf ("%d", &t);
while (t --)
{
scanf ("%d %d", &p, &q);
G[0].clear();
G[0].resize(p+1);
G[1].clear();
G[1].resize(p+1);

for (int i=0; i<q; i++)
{
int s, e, w;
scanf ("%d %d %d", &s, &e, &w);
G[0][s].push_back (Egde(e, w));
G[1][e].push_back (Egde(s, w));
}

__int64 sum = 0;
spfa (0, 1);
for (int i=1; i<=p; i++)
sum += dist[i];
spfa (1, 1);
for (int i=1; i<=p; i++)
sum += dist[i];
printf ("%I64d\n", sum);

}
return 0;
}

void spfa (int x, int s)
{
Egde pn;
queue<Egde>que;
memset (vis, false, sizeof(vis));
init();
pn.e = s, pn.w = 0;
dist[s] = 0;
que.push (pn);
vis[pn.e] = true;
while (!que.empty())
{
pn = que.front();
que.pop();
vis[pn.e] = false;
int len = G[x][pn.e].size();
for (int i=0; i<len; i++)
{
Egde p = G[x][pn.e][i];
if (dist[p.e] > dist[pn.e] + p.w)
{
dist[p.e] = dist[pn.e] + p.w;
if (!vis[p.e])
{
vis[p.e] = true;
que.push(p);
}
}
}
}
}


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