反向存边(逆图)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define max1 1001
#define max2 100001
int n,m,dis[max1],sum=0;
vector<int>a[max1],b[max1],c[max1],d[max1];
queue<int>q;
bool pd[max1];
inline int read()
{
    int k=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())
      if(c=='-') f=-1;
    for(;isdigit(c);c=getchar())
      k=k*10+c-'0';
    return k*f;
}
void spfa1()
{
    memset(dis,127,sizeof(dis));
    memset(pd,0,sizeof(pd));
    q.push(1); pd[1]=1; dis[1]=0;
    while(!q.empty())
    {
        int now=q.front(); q.pop(); pd[now]=0;
        for(int i=0;i<a[now].size();i++)
        {
            int next=a[now][i];
            int l=b[now][i];
            if(dis[next]>dis[now]+l)
            {
                dis[next]=dis[now]+l;
                if(!pd[next])
                {
                    pd[next]=1;
                    q.push(next);
                }
            }
        }
    }
}
void spfa2()
{
    memset(dis,127,sizeof(dis));
    memset(pd,0,sizeof(pd));
    q.push(1); pd[1]=1; dis[1]=0;
    while(!q.empty())
    {
        int now=q.front(); q.pop(); pd[now]=0;
        for(int i=0;i<c[now].size();i++)
        {
            int next=c[now][i];
            int l=d[now][i];
            if(dis[next]>dis[now]+l)
            {
                dis[next]=dis[now]+l;
                if(!pd[next])
                {
                    pd[next]=1;
                    q.push(next);
                }
            }
        }
    }
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        u=read(); v=read(); w=read();
        a[u].push_back(v); b[u].push_back(w);
        c[v].push_back(u); d[v].push_back(w);
    }
    spfa1();
    for(int i=2;i<=n;i++)
    sum+=dis[i];
    spfa2();
    for(int i=2;i<=n;i++)
    sum+=dis[i];
    cout<<sum;
    return 0;
}

洛谷 P1629 邮递员送信

一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。

思路: 1.先求1到各个点的最短路

2.再求各个点到1的最短路(反向存边再求1到各个点的最短路,即为原图中各个点到1的最短路)

可用范围:1.有向图

2.多点到同一点的最短路

posted @ 2017-11-19 10:30  kojoker  阅读(276)  评论(0)    收藏  举报