您的位置:首页 > 其它

PKU 1511 Invitation Cards (SPFA+邻接表)

2013-07-31 14:33 204 查看
题目链接:点击打开链接

        题目需要求从原点到所有点的最短距离之和和所有点到原点的最短距离之和,在求所有点到原点最短距离的时候用到了一个技巧:即把图反向,求原点到所有其他点的最短距离,这样用一次SPFA就可以将所有点到原点的最短距离求出来了。

 

        另外也没什么好说的,纯SPFA。另外用优化到VlogE的dijkstra貌似也能过,有空的时候再写个。

 

代码如下:

 

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <queue>
using namespace std;

#define MAX 1000009
#define INF 1<<30
struct ENode
{
int to, cost, next;
} enode[MAX * 4];

int NE = 0;
int OriginHead[MAX], RevHead[MAX];
int dist[MAX];

void insertEdge( int from, int to, int cost )
{
enode[NE].cost = cost; enode[NE].to = to; enode[NE].next = OriginHead[from]; OriginHead[from] = NE++;
enode[NE].cost = cost; enode[NE].to = from; enode[NE].next = RevHead[to]; RevHead[to] = NE++;
}

void initDist( int n )
{
for (int i=0; i<=n; i++) dist[i] = INF;
dist[1] = 0;
}

int inQueue[MAX];
queue<int> Q;
void SPFA( int *Head )
{
inQueue[1] = 1;
Q.push(1);
while ( ! Q.empty() )
{
int q = Q.front();
Q.pop();
inQueue[q] = 0;
for ( int i=Head[q]; i!=-1; i=enode[i].next )
{
int e = enode[i].to;
if ( dist[q] + enode[i].cost < dist[e] )
{
dist[e] = dist[q] + enode[i].cost;
if ( !inQueue[e] )
{
inQueue[e] = 1;
Q.push( e );
}
}
}
}
}

long long getTotal( int n )
{
long long ret = 0;
for (int i=2; i<=n; i++)
ret += dist[i];
return ret;
}

int main( )
{
int T;
cin >> T;

while( T-- )
{
int n, m;
scanf("%d%d", &n, &m);

memset( OriginHead, -1, sizeof(OriginHead) );
memset( RevHead, -1, sizeof(RevHead) );
NE = 0;
for (int i=0; i<m; i++)
{
int from, to, cost;
scanf( "%d%d%d", &from, &to, &cost );
insertEdge( from, to, cost );
}

initDist( n );
memset( inQueue, 0, sizeof(inQueue) );
SPFA( OriginHead );
long long int ans = 0;
ans += getTotal( n );

//cout << ans << endl;
initDist( n );
memset( inQueue, 0, sizeof(inQueue) );
SPFA( RevHead );
ans += getTotal( n );

cout << ans << endl;
}

return 0;
}


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