班级娱乐赛 K短路计数

K短路计数

  • 同学出的题目,有原题的,但找不到了。

Description

  • 题目背景(来源):小 L 从《挑战程序设计竞赛》中翻到了一道图论(暴力)好题。

    给定一个 n 个定顶点,边长为 1 的有向图邻接矩阵。求这个图中长度为 k 的不同的路径

    总数。(不懂看样例)

    1.路径中同一条边可经过多次。

    2.输出答案对(1e7)+7 取模。

    3.图中会有自环。

Input

  • 输入文件名为 count.in。

    输入第一行为两个用空格隔开正整数,分别为 n 和 k 的值。

    接下来输入 n 行(一个普通的邻接矩阵(不懂看样例)),

    每行 n 个用空格隔开的数字(1/0),代表着从 u 到 v(有/没有)连着一条有向边。

Output

  • 输出文件名为 count.out。

    输出一个整数,为图中长度为 k 的路径总数。

Sample Input

3 2

0 1 0

1 0 1

1 0 0

Sample Output

5

题解:

  • 矩阵乘法。
  • 会了就是裸题,不会的话,还挺有思考价值的。
  • 思考原图,如果将原图每个位置的值相加,答案是长度为1的的路径数,显然。
  • 那么,如果长度要为2,就要在原图的基础上,枚举一次中转点。例如,有3个点。原来1 -> 2是一条路,这时我就要尝试以2为中转点,看看2到1/2/3有没有路。假设2 -> 3有两条路。那么1 -> 3就有1 * 2 = 2路。
  • 仔细观察,发现以一个点为中转点进行尝试时,刚好跟矩阵乘法的运算顺序是一样的。
  • 那么每枚举一个中转点等价于做一个矩阵乘法。那么答案就是(原图矩阵的k次方)所以位置元素之和了。
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 105
#define hry 10000007
#define int long long
#define re register
using namespace std;

struct A
{
    int m[N][N];
    A() {memset(m, 0, sizeof(m));}
} a;
int n, k, ans;

inline A mul(A x, A y)
{
    A z;
    for(re int i =1 ; i <= n; i++)
        for(re int j = 1; j <= n; j++)
            for(re int k = 1; k <= n; k++)
                z.m[i][j] += x.m[i][k] * y.m[k][j],
                z.m[i][j] %= hry;
    return z;
}

inline A power(A a, int b)
{
    A r = a, base = a;
    while(b)
    {
        if(b & 1) r = mul(r, base);
        base = mul(base, base);
        b >>= 1;
    }
    return r;
}

signed main()
{
    cin >> n >> k;
    for(re int i = 1; i <= n; i++)
        for(re int j = 1; j <= n; j++)
            cin >> a.m[i][j];
    a = power(a, k - 1);
    for(re int i = 1; i <= n; i++)
        for(re int j = 1; j <= n; j++)
            ans += a.m[i][j], ans %= hry;
    cout << ans;
    return 0;
}

原文地址:https://www.cnblogs.com/BigYellowDog/p/11386166.html

时间: 2024-08-28 23:27:04

班级娱乐赛 K短路计数的相关文章

最短路与次短路计数

poj  3464  http://poj.org/problem?id=3463 问最短路的条数+比最短路权值大 1  的条数 做法  比较一下次短路和最短路的值  若次短路恰好比最短路大1,答案为最短路+次短路条数,否则答案就是最短路条数 1 #include<cstdio> 2 const int inf=0x3f3f3f3f; 3 class Count_short_path { ///最短路与次短路计数Dijkstra_o(MV^2) 4 typedef int typec;///边

题解——[JSOI2007]重要的城市 floyd:最短路计数

---题面--- 题解: 其实感觉还是比较妙的,第一眼看题想到floyd统计最短路条数, 注意到对于任意两点x,y而言,floyd将会枚举其最短路所可能经过的所有中转点, 因此我们可以直接分别统计对于所有二元组而言,最短路上必须经过的中转点, 最后遍历一次所有统计到的结果,并用bool数组标记一个地点是否被作为过中转点 最后再遍历一次bool数组,如果是中转点就输出即可 注意有多条最短路并不一定意味着这两个点之间的最短路就没有关键点, 因为这几条最短路可能有一个(或多个)共同用点,这时共同用点将

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

poj2449:第k短路问题

Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story. "Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One

图的第k短路

[问题描述] 给你一个有向图,求从1到n的第k短路. [解法] SPFA+A*搜索. 1 A*算法 A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的: h(n)=f(n)+g(n) 其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价.另外定义h'(n)为n到目标节点最佳路径的实际值.如果h'(n)≥h(n)则如果存在从初始状态走到目标状态的最小代价的解,那么用该估价函数搜索的算法就叫A*

POJ 2499 A*求第K短路

DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. // 大概懂思路了.A*算法需要的估价函数里的两个函数.一个是起点到当前点的消耗. //一个是当前点到目标点的估测消耗.所以需要用Dijstra或者Spfa求出目标点到所有点的最短路. //然后就可以用A*算法来求了. // 确实.学了位运算.链式表. #include<cstdio> #include<iostream> #include<queue> #include<

poj2449 Remmarguts&#39; Date,第K短路

点击打开链接 SPFA  + A* #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; struct node { int v, dis, f, next; friend bool operator <(node a, node b){ return a.f>b.f; } }; const int INF =

poj 2449 Remmarguts&#39; Date k短路

/*poj 2449 k短路 A* 估价函数是 s到i的距离+i到t的距离 */ #include<cstdio> #include<queue> #include<vector> #define inf 1e7 #define maxn 100010 using namespace std; int n,m,S,T,K,num1,num2,head1[maxn],head2[maxn],dis[maxn]; int q[maxn],hea,tai,f[maxn],cn

POJ 2449Remmarguts&#39; Date K短路模板 A*+SPFA

太水了我不想说了,模板在这里 14312K 313MS 1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int v[100010],v2[100010],c[100010],c2[100010],s,t,k,duin; 7 int n,m,point[1010],next[100010],cnt=0,