POJ_1511_最短路径_spfa

//============================================================================
// Name        : POJ_1511.cpp
// Author      : tiger
// Version     :
// Copyright   : Your copyright notice
// Description : 求两遍单源最短路径之和即可,第二遍要把图反转
//    zhangzhenhu 1511 Accepted 36880K 1938MS G++
//============================================================================

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN =  1000005;
struct NODE
{
 int to;
 int value;
 NODE *next;
 void intial()
 {
  to = 0;
  value = 0;
  next = 0;
 }
};

NODE *mat1[MAXN], *mat2[MAXN];
queue<int> q;
NODE pool[MAXN *2 + 2];
int counts;
long long  spfa(int n, int s, NODE *mat[])
{
 int i, k;
 long long sum;
 NODE *p;
 int min[MAXN];
 bool v[MAXN];
 for (i = 0; i < n; i++)
 {
  min[i] = 1000000000;
  v[i] = false;
 }
 min[s] = 0;
 v[s] = true;
 q.push(s);
 while (!q.empty())
 {
  k = q.front();
  q.pop();
  v[k] = false;
  p = mat[k];
  while (p)
  {
   if (min[k] + p->value < min[p->to])
   {
    min[p->to] = min[k] + p->value;
    if (!v[p->to])
    {
     q.push(p->to);
     v[p->to] = true;
    }
   }
   p = p->next;
  }
 }
 sum = 0;
 for (i = 0; i < n; i++)
  sum += min[i];
 return sum;
}

int main()
{

 freopen("in", "r", stdin);

 int t, P, Q;
 int i, a, b, c;
 long long sum;
 NODE *p;
 scanf("%d", &t);
 while (t--)
 {
  scanf("%d %d", &P, &Q);
  for (i = 0; i < P; i++)
  {
   mat1[i] = NULL;
   mat2[i] = NULL;
  }
  counts = 0;
  for (i = 0; i < Q; i++)
  {
   scanf("%d %d %d", &a, &b, &c);
   a--;
   b--;
   p = mat1[a];
   mat1[a] = pool + counts;
   mat1[a]->intial();
   mat1[a]->to = b;
   mat1[a]->value = c;
   mat1[a]->next = p;

   p = mat2[b];
   mat2[b] = pool + Q + 1 + counts;
   mat2[b]->intial();
   mat2[b]->to = a;
   mat2[b]->value = c;
   mat2[b]->next = p;
   counts++;

  }
  sum = spfa(P, 0, mat1) + spfa(P, 0, mat2);
  printf("%lld/n", sum);
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值