POJ1511-Invitation Cards

本文详细介绍了一种用于解决最短路径问题的SPFA算法,并通过一个具体的编程实例展示了该算法的应用过程。文章首先初始化了必要的数据结构,然后使用SPFA算法进行两轮计算,最后输出所有节点到起点的距离之和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

模板题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define INF 1000000005
#define MAXN 1000005
using namespace std;
int head[MAXN],dis[MAXN],vis[MAXN],in[MAXN],s[MAXN],t[MAXN],w[MAXN],n,m,tot;
struct node
{
    int v,w,next;
}edge[MAXN];
queue<int> Q;
void init()
{
    int i;
    tot=0;
    memset(head,-1,sizeof(head));
}
void add(int s,int t,int w)
{
     edge[++tot].v=t;
     edge[tot].w=w;
     edge[tot].next=head[s];
     head[s]=tot;
}
int spfa()
{
    int i,j,k;
    memset(vis,0,sizeof(int)*(n+1));
    memset(in,0,sizeof(int)*(n+1));
    for(i=1;i<=n;i++)
       dis[i]=INF;
    Q.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!Q.empty())
    {
          i=Q.front();
          Q.pop();
          for(j=head[i];j!=-1;j=edge[j].next)
          {
              k=edge[j].v;
              if(dis[i]+edge[j].w<dis[k])
              {
                 dis[k]=dis[i]+edge[j].w;
                 if(!vis[k])
                 {
                    Q.push(k);
                    in[k]++;
                    if(in[k]>=n) 
                       return -1;
                    vis[k]=1;
                 }
              }
          }
    }
}
int main(void)
{
    int T,i;
    long long ans=0;
    scanf("%d",&T);
    while(T--)
    {
          init();
          scanf("%d%d",&n,&m);
          for(i=0;i<m;i++)
          {
              scanf("%d%d%d",&s[i],&t[i],&w[i]);
              add(s[i],t[i],w[i]);
          }
          spfa();
          ans=0;
          for(i=1;i<=n;i++)
              ans+=dis[i];
          init();
          for(i=0;i<m;i++)
              add(t[i],s[i],w[i]);
          spfa();
          for(i=1;i<=n;i++)
              ans+=dis[i];
          printf("%I64d\n",ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/YogurtShen/archive/2012/08/30/2664319.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值