poj 1511 spfa

来源:互联网 发布:网络机顶盒app 编辑:程序博客网 时间:2024/05/16 10:44

【题意】

给定一个有向图,求从源点到其他各点的往返最短路径和。且这个图有一个性质:任何一个环都会经过源点。

【题解】

建正反两图,求最短路。spfa。。。

注意用long long ,且输出时用printf("%I64d",ans);

【代码】

#include <iostream>#include <queue>using namespace std;const int maxn=1000005,oo=1000000005;struct edge{       int y,w,next;}e[maxn];queue<int> q;int h[maxn],d[maxn],x[maxn],y[maxn],w[maxn];bool v[maxn];int n,m,tot;void ins(int x,int y,int w){     e[++tot].y=y;e[tot].w=w;     e[tot].next=h[x];h[x]=tot;}void spfa(){    int i,x,y;    for (i=1;i<=n;i++)    {        d[i]=oo;v[i]=false;    }    q.push(1);    v[1]=true;d[1]=0;    while (!q.empty())    {          x=q.front();          q.pop();          for (i=h[x];i;i=e[i].next)          {              y=e[i].y;              if (d[x]+e[i].w<d[y])              {                 d[y]=d[x]+e[i].w;                 if (!v[y])                 {                    v[y]=true;                    q.push(y);                 }              }          }    }}int main(){    freopen("pin.txt","r",stdin);    freopen("pou.txt","w",stdout);    int cc,i;    long long ans=0;    scanf("%d",&cc);    while (cc--)    {          memset(h,0,sizeof(h));          tot=0;          scanf("%d%d",&n,&m);          for (i=0;i<m;i++)          {              scanf("%d%d%d",&x[i],&y[i],&w[i]);              ins(x[i],y[i],w[i]);          }          spfa();          ans=0;          for (i=1;i<=n;i++)              ans+=d[i];          memset(h,0,sizeof(h));          tot=0;          for (i=0;i<m;i++)              ins(y[i],x[i],w[i]);          spfa();          for (i=1;i<=n;i++)              ans+=d[i];          printf("%I64d\n",ans);    }    return 0;}