zoukankan      html  css  js  c++  java
  • 城堡

        普通的的图论题

    思路:先将边读入,建图。

    对图跑一遍SPFA ,找出 点1 到各点的最短路。

    再跑一遍SPFA , 不过这次找的是树中 与 点i 相连接 并且 当前扫描点的dis 值 加上 i 到当前点的边权等于i 点dis值的边的数量

    最后运用什么乘法原理,即    问题的答案是由m 个答案构成 ,第一步的答案为n1 种,第二步为n2 种, 第三步为n3种 ,则第n步的答案 有 m * n种(大意)

    把答案乘起来。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define Max 1000000
    #define mod 2147483647
    #define INF 100000000
    using namespace std;
    int N, M;
    int Total;
    int head [Max / 1000 | 1];
    int dis [Max / 1000 | 1], queue [Max / 1000 | 1];
    bool visit [Max / 1000 | 1];
    long long Answer , count [Max / 1000 | 1];
    struct node
    {
        int next;
        int node;
        int worth;
    }Edge [Max];
    inline void AddEdge (int x, int y, int w)   // 加边 
    {
            Edge [++Total].next = head [x];
            head [x] = Total;
            Edge [Total].node = y;
            Edge [Total].worth = w; 
    }
    inline int Judge (int &x)
    {
        return x = x + 1 == N ? 0 : x + 1;   //如果x + 1 == n 表明已经到了终点, 再指回起点 
    }
    inline void SPFA (int x)   //  SPFA最短路  
    {
        int head_cur = 0, tail = 0;
        for (int i = 1; i <= N; i++)
            dis [i] = INF;
        dis [x] = 0;
        visit [x] = true;
        queue [Judge (tail)] = x;
        while (head_cur != tail)
        {
            int cur = queue [Judge (head_cur)];
            visit [cur] = false;
            for (int i = head [cur]; i; i = Edge [i].next)
            {
                int node = Edge [i].node ;
                if (dis [node] > dis [cur] + Edge [i].worth)
                {
                    dis [node] = dis [cur] + Edge [i].worth;
                    if (! visit [node])
                    {
                        visit [node] = true;
                        queue [Judge (tail)] = node;
                    }
                }
            }
        }
    }
    int main()
    {
        ios :: sync_with_stdio (false);
        cin >> N >> M;
        int x, y, w;
        for (int i = 1; i <= M; i++)
        {
            cin >> x >> y >> w;
            AddEdge (x, y, w);        //加到图中 
            AddEdge (y, x, w);          //因为是无向图,所以 (x, y)(y, x) 都要建边 
        }
        SPFA (1);               // 跑一遍SPFA找出 点1 到各点的最短路 
        int head_cur = 0, tail = 0;   
        queue [Judge (tail)] = 1;
        visit [1] = true;
        count [1] = 1;               // 接下来 再跑一遍 SPFA,找出树中的最短路  
        while (head_cur != tail)
        {
            int cur = queue [Judge (head_cur)];
            for (int i = head [cur]; i; i = Edge [i].next)
            {
                int node = Edge [i].node;
                if (dis [node] == dis [cur] + Edge [i].worth )
                {
                    count[node]++;   // 记录 与i点相连接 并且 当前扫描的点的dis值 加上 边权 等于 i点 的dis值 的 边的数量 
                    if (count [node] >= mod)
                        count [node] -= mod;
                    if (!visit [node])
                    {
                        queue [Judge (tail)] = node;
                        visit [node] = true;
                    }
                } 
            }
        }
        Answer = 1;
        for (int i = 1; i <= N; i++)
        {
            Answer *= count [i];         //利用  X X 乘法原理 , 把每个点满足的数量 乘起来 ,即为答案 
              if (Answer >= mod) 
                Answer %= mod;
        }
        printf ("%d
    ", (int) Answer);
        return 0;
    }
  • 相关阅读:
    node代码打包为 exe文件---端口进程关闭demo
    java 中几种常用数据结构
    Java 多线程编程
    【java排序】 归并排序算法、堆排序算法
    【java排序】 选择排序,插入排序,希尔算法
    【java排序】冒泡排序、快速排序
    springMVC执行流程及原理
    Java反射机制详解
    【Java并发编程】:并发新特性—信号量Semaphore
    【Java并发编程】:并发新特性—障碍器CyclicBarrier
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6060130.html
Copyright © 2011-2022 走看看