有趣的最短路结论

P1629 邮递员送信

 

 

 

结论:

对于有向图,在反图中的从 1 出发到其他点的最短路就是在原图中从其他点出发到达 1 的最短路!!

 

 

AC码:

#include<bits/stdc++.h>
//typedef long long ll;
#define rd read()
#define int long long
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define neg(i,a,b) for(int i=(a);i>=(b);i--)
const int Max=100010;
const int inf=0x7f7f7f7f;
const int Mod=1e9+7;
using namespace std;

int n,m,s,d,cnt=0,t;
int diis[2*Max];
bool vis[2*Max];
int x[Max],y[Max];
inline int read()
{
    int x=0,k=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*k;
}

struct edge
{
    int to,l,next;
}Edge[2*Max];
int head[2*Max];

struct node
{
    int dis,id;
    bool operator <(const node &x)const
    {
        return x.dis<dis;
    }
};

priority_queue<node> q;

void add_edge(int v,int u,int d)
{
    Edge[++cnt].next=head[v];
    Edge[cnt].to=u;
    Edge[cnt].l=d;
    head[v]=cnt;
}

void dijkstra()
{
    pos(i,1,n*2) diis[i]=inf;
    diis[s]=0;
    q.push((node){0,s});
    memset(vis,0,sizeof(vis));
    while(!q.empty())
    {
        node now=q.top();
        q.pop();
        int diss=now.dis,idd=now.id;

        if(vis[idd]) continue;
        vis[idd]=1;

        for(int i=head[idd];i;i=Edge[i].next)
        {
            int too=Edge[i].to;
            if(diis[idd]+Edge[i].l<diis[too])
            {
                diis[too]=diis[idd]+Edge[i].l;
                if(!vis[too])  
                {
                    q.push((node){diis[too],too});
                }
            }
        }
    }
}


signed main()
{
    while(cin>>n>>m)
    {
        cnt=0;  
        pos(i,1,m)
        {
            int v=rd,u=rd,w=rd;
            add_edge(v,u,w);
            add_edge(u+n,v+n,w);
        }
        int ans=0;
        s=1;
        dijkstra();
        pos(i,1,n) ans+=diis[i];
        s=n+1;
        dijkstra();
        pos(i,1+n,n*2) ans+=diis[i];
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2021-04-27 14:44  juuich  阅读(58)  评论(0编辑  收藏  举报