• POJ 1511 spfa求最短回路


    http://poj.org/problem?id=1511

    题意:(图论147)。求从起点到各个点的最短回路。

    分析:用两次spfa就行了。第一次spfa是从出发点start到各个点,求一次最短距离,第二次spfa是从各个点反向求到出发点的最短距离。

    处理:第一次spfa只要保存正向边,第二次用反向边进行spfa就可以了。最后把两次求得的距离相加就是最短回路。

    View Code
    // I'm the Topcoder
    //C
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <math.h>
    #include <time.h>
    //C++
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <cctype>
    #include <stack>
    #include <string>
    #include <list>
    #include <queue>
    #include <map>
    #include <vector>
    #include <deque>
    #include <set>
    using namespace std;
    
    //*************************OUTPUT*************************
    #ifdef WIN32
    #define INT64 "%I64d"
    #define UINT64 "%I64u"
    #else
    #define INT64 "%lld"
    #define UINT64 "%llu"
    #endif
    
    //**************************CONSTANT***********************
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    #define PI acos(-1.)
    #define PI2 asin (1.);
    typedef long long LL;
    //typedef __int64 LL;   //codeforces
    typedef unsigned int ui;
    typedef unsigned long long ui64;
    #define MP make_pair
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    #define pb push_back
    #define mp make_pair
    
    //***************************SENTENCE************************
    #define CL(a,b) memset (a, b, sizeof (a))
    #define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b))
    #define sqr3(a,b,c) sqrt((double)(a)*(a) + (double)(b)*(b) + (double)(c)*(c))
    
    //****************************FUNCTION************************
    template <typename T> double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); }
    template <class T> inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; }
    template <typename T> inline T square(T va, T vb) { return va * va + vb * vb; }
    
    // aply for the memory of the stack
    //#pragma comment (linker, "/STACK:1024000000,1024000000")
    //end
    
    const int maxn = 1000000+100;
    struct node{
        int to;
        int next;
        long long weight;
    };
    node edge[maxn],edge1[maxn];//保存边的起点和终点
    int n,m;
    long long val;
    int tot,tot1;
    int src;//起点
    int head[maxn],head1[maxn];
    int visit[maxn],visit1[maxn];
    long long dis[maxn],dis1[maxn];
    
    void add(int a,int b,long long c){
        edge[tot].to=b;
        edge[tot].weight=c;
        edge[tot].next=head[a];
        head[a]=tot++;
    }
    
    void add1(int a,int b,long long c){
        edge1[tot1].to=b;
        edge1[tot1].weight=c;
        edge1[tot1].next=head1[a];
        head1[a]=tot1++;
    }
    
    void spfa(){
        //初始化
        for(int i=1;i<=n;i++){
            dis[i]=INF;
            visit[i]=0;//访问标记
        }
        dis[src]=0; visit[src]=1;
        int u;
        int v;
        queue<int> Q;//优先队列
        Q.push(src);
        while(!Q.empty()){
            u=Q.front();
            Q.pop();
             visit[u]=0;//必须是0,这题是1也能过不过是错的
           // visit[u]=1;
            for(int i=head[u];i!=-1;i=edge[i].next){
                v=edge[i].to;
                if(dis[v]>dis[u]+edge[i].weight){
                    dis[v]=dis[u]+edge[i].weight;
                    if(!visit[v]){
                        Q.push(v);
                        visit[v]=1;
                    }
                }
            }
        }
    }
    
    
    void spfa1(){
        //初始化
        for(int i=1;i<=n;i++){
            dis1[i]=INF;  visit1[i]=0;
        }
        dis1[src]=0;  visit1[src]=1;
        int u,v;
        queue<int> Q;
        Q.push(src);
        while(!Q.empty()){
            u=Q.front();
            Q.pop();
             visit[u]=0;//必须是0,这题是1也能过不过是错的
            //visit1[u]=1;
            for(int i=head1[u];i!=-1;i=edge1[i].next){
                v=edge1[i].to;
                if(dis1[v]>dis1[u]+edge1[i].weight){
                    dis1[v]=dis1[u]+edge1[i].weight;
                    if(!visit1[v]){
                        Q.push(v);
                        visit1[v]=1;
                    }
                }
            }
        }
    }
    
    int main(){
        int a,b,cas;
        scanf("%d",&cas);
        while(cas--){
            scanf("%d%d",&n,&m);
            tot=tot1=0;//边的条数
            for(int i=1;i<=n;i++){
                head[i]=-1;
                head1[i]=-1;
            }
            for(int i=1;i<=m;i++){
                scanf("%d%d%lld",&a,&b,&val);
                add(a,b,val);//正向边
                add1(b,a,val);//反向边
            }
            src=1;//起点(终点)
            spfa();
            spfa1();
            long long sum=0;
            for(int i=2;i<=n;i++){
                sum+=dis[i]+dis1[i];
            }
            printf("%lld\n",sum);
        }
        return 0;
    }
  • 相关阅读:
    js面对对象编程
    MyBatis -- 一步步教你使用MyBatis
    简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
    2014年工作中遇到的20个问题:181-200
    2014年工作中遇到的20个问题:181-200
    老雷:思儿壮志小诗一首(老爸写得都比我好,让我这个文艺青年情何以堪)(家人对幸福美好生活的追求,就是我的奋斗目标)
    老雷:思儿壮志小诗一首(老爸写得都比我好,让我这个文艺青年情何以堪)(家人对幸福美好生活的追求,就是我的奋斗目标)
    雷观(十三):功能优先,开发与重构并举,性能殿后
    雷观(十三):功能优先,开发与重构并举,性能殿后
    URL传递中文参数,大坑一枚,Windows与Linux效果竟然不一致(两种解决方法)
  • 原文地址:https://www.cnblogs.com/lanjiangzhou/p/2995774.html
Copyright © 2020-2023  润新知