poj 1511 Invitation Cards

单元最短路问题,正向建一次图,反向建一次图,把两次spfa()的结果相加即可。


#include<stdio.h>
#include<string.h>
struct Node{
long long start;
long long end;
long long len;
long long next;
}node[1000010],node1[1000010];
long long dist[1000010],vis[1000010],head[1000010],q[4000020],head1[1000010];
long long n,t,tot,front,rear;
void spfa()
{
   long long u,v;
   memset(vis,0,sizeof(vis));
   for(int i=0;i<=n;i++)
     dist[i]=1000000010;
   vis[1]=1;
   dist[1]=0;
   front=rear=0;
   q[front++]=1;
   while(front!=rear)
   {
     u=q[rear++];
     vis[u]=0;
     for(int i=head[u];i!=-1;i=node[i].next)
     {
        v=node[i].end;
        if(dist[v]>dist[u]+node[i].len)
        {
           dist[v]=dist[u]+node[i].len;
           if(vis[v]==0)
           {
             q[front++]=v;
             vis[v]=1;
           }
        }
     }
    }
}
void spfa1()
{
   long long u,v;
   memset(vis,0,sizeof(vis));
   for(int i=0;i<=n;i++)
     dist[i]=1000000010;
   vis[1]=1;
   dist[1]=0;
   front=rear=0;
   q[front++]=1;
   while(front!=rear)
   {
     u=q[rear++];
     vis[u]=0;
     for(int i=head1[u];i!=-1;i=node1[i].next)
     {
        v=node1[i].start;
        if(dist[v]>dist[u]+node1[i].len)
        {
           dist[v]=dist[u]+node1[i].len;
           if(vis[v]==0)
           {
             q[front++]=v;
             vis[v]=1;
           }
        }
     }
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
      scanf("%d%d",&n,&tot);
      memset(head,-1,sizeof(head));
      memset(head1,-1,sizeof(head1));
      for(int i=1,j=1;i<=tot,j<=tot;i++,j++)
      {
        scanf("%d%d%d",&node[i].start,&node[i].end,&node[i].len); 
        node1[j].start=node[i].start;
        node1[j].end=node[i].end;
        node1[j].len=node[i].len;
        node[i].next=head[node[i].start];
        head[node[i].start]=i;
        node1[j].next=head1[node1[j].end];
        head1[node1[j].end]=j;
      }
      spfa();
      long long sum1=0;
      for(int i=1;i<=n;i++)
      {
        sum1+=dist[i];
        //printf("%d!\n",dist[i]);
      }
      spfa1();
      long long sum2=0;
      for(int i=1;i<=n;i++)
      {
        sum2+=dist[i];
        //printf("%d!!\n",dist[i]);
      } 
      printf("%I64d\n",sum1+sum2);
   }
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值