• The Shortest Path in Nya Graph---hdu4725(spfa+扩点建图)


    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4725

     有n个点,每个点都有一个层l[i],相邻层的边有一条无向带权边,权值为都为C,另外还有m条边,每条边对应的u v w 

    最后求1到n的最小权值和是多少;

    如果直接建图的话会TLE;这里把层数扩展为点n+1----n+n;然后在连接各种关系对应的图,最后用spfa求最短路即可,注意扩点之后点的个数;

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <stack>
    #include <algorithm>
    #include <map>
    #include <string>
    typedef long long LL;
    #define INF 0x3f3f3f3f
    #define met(a, b) memset(a, b, sizeof(a))
    #define N 200005
    
    using namespace std;
    
    struct node
    {
        int v, w, Next;
    }G[N*3];
    
    int n, m, c, dist[N], vis[N], l[N], v[N];
    
    int Head[N], cnt;
    void Add(int u, int v, int w)
    {
        G[cnt].v = v;
        G[cnt].w = w;
        G[cnt].Next = Head[u];
        Head[u] = cnt++;
    }
    
    int spfa()
    {
        for(int i=1; i<=n*2+5; i++)
            dist[i] = INF;
        met(vis, 0);
        queue<int>Q;
        Q.push(1);
        vis[1] = 1;
        dist[1] = 0;
        while(!Q.empty())
        {
            int p = Q.front();Q.pop();
            vis[p] = 0;
            for(int i=Head[p]; i!=-1; i=G[i].Next)
            {
                int q = G[i].v;
                if(dist[q] > dist[p]+G[i].w)
                {
                    dist[q] = dist[p]+G[i].w;
                    if(!vis[q])
                    {
                        vis[q] = 1;
                        Q.push(q);
                    }
                }
            }
        }
        return dist[n];
    }
    
    int main()
    {
        int T, t = 1;
        scanf("%d", &T);
        while(T--)
        {
            met(Head, -1);
            met(v, 0);
            cnt = 0;
    
            scanf("%d %d %d", &n, &m, &c);
    
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &l[i]);
                v[l[i]] = 1;
            }
    
            for(int i=1; i<n; i++)
            {
                if(v[i] && v[i+1])
                {
                    Add(n+i, n+i+1, c);///层与层之间连边;
                    Add(n+i+1, n+i, c);
                }
            }
            for(int i=1; i<=n; i++)
            {
                Add(n+l[i], i, 0);///当前点与它所在的层连边,边为0;
                if(l[i]!=1) Add(i, n+l[i]-1, c);///点和层间进行连边;
                if(l[i]!=n) Add(i, n+l[i]+1, c);
            }
    
            for(int i=1; i<=m; i++)
            {
                int u, v, w;
                scanf("%d %d %d", &u, &v, &w);
                Add(u, v, w);
                Add(v, u, w);
            }
            int ans = spfa();
            if(ans == INF) ans = -1;
            printf("Case #%d: %d
    ", t++, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    fedora-coreos 试用podman
    博客主题更新了
    C stdarg.h:可变参数va_list、va_arg等宏的使用及原理简介
    静态、动态链接库的生成及使用
    notfastjson项目介绍
    The ANSI C Programming Language:C语言预处理机制
    语法分析:LL(1)语法分析的实现及扩展的巴科斯范式
    语法分析:LL(1)分析
    计算机系统基础:计算机系统概述
    计算机系统基础:数据的表示和存储
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5829521.html
Copyright © 2020-2023  润新知