zoukankan      html  css  js  c++  java
  • P1342 请柬 建反图+dijkstra

    题目链接

    一句话题意:喊你求出从1出发到所有点的最短路以及所有点的最短路到1的最短路之和。

    从1开始跑最短路很容易,直接一遍堆优化dijkstra就完了。

    对于其他点到1的最短路又怎么求,不可能一个一个的求,所以想到之前暑假讲关于图论的技巧——建反图。

    这样的话问题就迎刃而解了,再在反图上从1开始跑一遍最短路就完了。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e6+7;
    const int inf=0x7fffffff;
    struct node1{
        int nxt,to,val;
    }edge1[maxn*3];
    struct node2{
        int nxt,to,val;
    }edge2[maxn*3];
    priority_queue<pair<long long ,int > >q1;
    priority_queue<pair<long long ,int > >q2;
    long long dis1[maxn],dis2[maxn];
    int cnt1,cnt2;
    int n,m;
    int x,y,v;
    int head1[maxn],head2[maxn];
    void add1(int x,int y,int v){
        edge1[++cnt1].nxt=head1[x];
        edge1[cnt1].to=y;
        edge1[cnt1].val=v;
        head1[x]=cnt1;
    } 
    void add2(int x,int y,int v){
        edge2[++cnt2].nxt=head2[x];
        edge2[cnt2].to=y;
        edge2[cnt2].val=v;
        head2[x]=cnt2;
    }
    bool vis1[maxn];
    long long ans1;
    void dijkstra1(int x){
        for(int i=1;i<=n;i++){
            dis1[i]=inf;
            vis1[i]=false;
        }
        dis1[x]=0;
        q1.push(make_pair(0,x));
        while(q1.size()){
            int u=q1.top().second;
            q1.pop();
            if(vis1[u]) continue;
            vis1[u]=true;
            for(int i=head1[u];i;i=edge1[i].nxt){
                int v=edge1[i].to;
                if(dis1[v]>dis1[u]+edge1[i].val){
                    dis1[v]=dis1[u]+edge1[i].val;
                    q1.push(make_pair(-dis1[v],v));
                }
            }
        }
        for(int i=1;i<=n;i++) ans1+=dis1[i];
    }
    long long ans2;
    bool vis2[maxn];
    void dijkstra2(int x){
        for(int i=1;i<=n;i++){
            vis2[i]=false;
            dis2[i]=inf;
        }
        dis2[x]=0;
        q2.push(make_pair(0,x));
        while(q2.size()!=0){
            int u=q2.top().second;
            q2.pop();
            if(vis2[u]) continue;
            for(int i=head2[u];i;i=edge2[i].nxt){
                int v=edge2[i].to;
                if(dis2[v]>dis2[u]+edge2[i].val){
                    dis2[v]=dis2[u]+edge2[i].val;
                    q2.push(make_pair(-dis2[v],v));
                }
            }
        }
        for(int i=1;i<=n;i++) ans2+=dis2[i];
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&v);
            add1(x,y,v);
            add2(y,x,v);
        }
        dijkstra1(1);
        dijkstra2(1);
        long long final=ans1+ans2;
        printf("%lld
    ",final);
        return 0;
    }
    View Code
  • 相关阅读:
    GTP (GPRS隧道协议(GPRSTunnellingProtocol))
    dns (域名系统)
    WSP (无线会话协议)
    http 超文本传输协议
    SSN 社会安全号码
    MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)
    dns
    C/C++中的预编译指令
    strstr 函数用法
    转Hibernate Annotation mappedBy注解理解
  • 原文地址:https://www.cnblogs.com/LJB666/p/11561117.html
Copyright © 2011-2022 走看看