給定一個有向圖,問從A點恰好走k步(允許重複經過邊)到達B點的方案數---矩陣乘法
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string.h> #include <vector> #include <queue> //hdu2157 #define mod 1000 using namespace std; /* 題目大意:給定一個有向圖,問從A點恰好走k步(允許重複經過邊)到達B點的方案數mod p的值 把給定的圖轉為鄰接矩陣,即A(i,j)=1當且僅當存在一條邊i->j。令C=A*A,那麼C(i,j)=ΣA(i,k)*A(k,j), 實際上就等於從點i到點j恰好經過2條邊的路徑數(列舉k為中轉點。 類似地,C*A(這裡的C已經是A*A)的第i行第j列就表示從i到j經過3條邊的路徑數。同理,如果要求經過k步的 路徑數,我們只需要二分求出A^k即可。 注意:矩陣多次冪可以防止爆棧(相比二分法求矩陣多次冪) */ int n; struct matrix { int a[25][25]; void init() { for(int j=0; j<25; ++j) { for(int t=0; t<25; ++t) a[j][t]=0; } } }p; matrix mul(matrix a1, matrix b1) { matrix q; q.init(); int t, j, k; for(j=0; j<n; ++j) { for(t=0; t<n; ++t) { for(k=0; k<n; ++k) { q.a[j][t]+=a1.a[j][k]*b1.a[k][t]; q.a[j][t]%=mod; } } } return q; } /* matrix f(int x) 如果用二分法來求矩陣快多次冪,需要遞迴多次(每遞迴一次就要申請一個矩陣空間),這樣很容易爆棧 { if(x==1)return p; matrix s=f(x/2); s=mul(s, s); if(x&1) s=mul(s, p); return s; } */ matrix f(int x) //矩陣多次冪可以防止爆棧 { matrix q, s=p; int t, j; for(j=0; j<n; ++j) //構建單位矩陣 { for(t=0; t<n; ++t) { if(j==t) q.a[j][t]=1; else q.a[j][t]=0; } } while(x) { if(x&1) q=mul(s, q); x=x>>1; s=mul(s, s); } return q; } int main() { int m ,t, T, s, k, s1, s2, g; while(scanf("%d%d", &n, &m)!=EOF) { if(n==0&&m==0)break; p.init(); for(t=0; t<m; ++t) { scanf("%d%d", &s, &g); p.a[s][g]=1; //有向的 } scanf("%d", &T); while(T--) { scanf("%d%d%d", &s1, &s2, &k); matrix result=f(k); printf("%d\n", result.a[s1][s2]); //s1到s2的路徑總數 } } return 0; }
相關推薦
給定一個有向圖,問從A點恰好走k步(允許重複經過邊)到達B點的方案數---矩陣乘法
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath>
[阿里筆試]以下是一個有向圖,我們從節點B開始進行深度優先遍歷(DFS),那麼以下5個序列中,所有正確的DFS序列是____。
題目(阿里筆試題):以下是一個有向圖,我們從節點B開始進行深度優先遍歷(DFS),那麼以下5個序列中,所有正確的DFS序列是__。 解析:深度優先遍歷是指優先探索完一條通路後才返回倒數第二個節點繼
Toposort Description 給出一個有向圖,判斷圖中是否存在迴路。 Input: 第1行:輸入圖的頂點個數N(1 ≤ N≤ 2,500)和C(圖的邊數,1 ≤ C ≤ 6,20
Toposort Description 給出一個有向圖,判斷圖中是否存在迴路。 Input: 第1行:輸入圖的頂點個數N(1 ≤ N≤ 2,500)和C(圖的邊數,1 ≤ C ≤ 6,200); 第2到C+1行中,第i+1行輸入兩個整數,分別表示第i條邊的起點和終點的編號
uva11090 給你一個有向圖,求出平均權值最小的環
B 【題目描述】 泡泡魚是一條調皮的魚,ta 的家住在一片珊瑚礁上。在 ta 的眼裡,這些珊瑚礁的形態 可以腦補成一個 n 個節點,m 條邊的帶權圖,在海水的腐蝕下,這些珊瑚礁形成了許多的 環,ta 想考考你能不能找出這些環中,權值的平均值最小的環。泡泡魚這麼聰明,ta
【HDU 4514】【樹的直徑 dfs或者並查集判斷環】【給定一個無向圖,圖可能是非連通的,如果圖中存在環,就輸出YES,否則就輸出樹的直徑】
描述: 湫湫系列故事——設計風景線 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 4610 Acc
程式設計師面試金典: 9.4樹與圖 4.2給定有向圖,設計一個演算法,找出兩個節點之間是否存在一條路徑。
#include <iostream> #include <stdio.h> #include <vector> #include <queue> using namespace std; /* 問題:給定有向圖,設計一個
poj3615 給你一個有向圖,然後對於特定的點A與B,要你求出A到B之間所有可行路徑的單段路距離最大值的最小值.
#include<cstdio> #include<algorithm> #define INF 1e9 using namespace std; const int maxn = 300+10; int n,m,t; int d[maxn][maxn]; void floy
poj3615 給你一個有向圖,然後對於特定的點A與B,要你求出A到B之間所有可行路徑的單段路距離最大值的最小值.
#include<cstdio> #include<algorithm> #define INF 1e9 using namespace std; const int maxn = 300+10; int n,m,t; int d[maxn][maxn
用dfs判斷一個有向圖是否有環
解決這個問題的演算法的思路是對一個節點u進行dfs,判斷是否能從u回到自己這個節點,即是否存在從u到u的迴路。 我們可以用一個color陣列代表每個結點的狀態,-1代表還沒被訪問,0代表正在被訪問,1代
Kosaraju 演算法求解一個有向圖的強連通分支個數
基本介紹 網上看了很多關於求解一個有向圖的強連通分支個數的演算法,其中最著名的莫過於: Kosaraju 演算法 看的比較暈! 過程如下: 1。 建立一個空的棧 S,並做一次 DFS 遍歷。在 DFS 遍歷中,當在遞迴呼叫 DSF 訪問鄰接頂點時,將
Java鄰接表表示加權有向圖,附dijkstra最短路徑演算法
圖這種adt(abstract data type)及相關的演算法,之前一直是我未曾涉足過的領域。 主要是作為一個小測試,在平常的工作中也用不著,就算面試,至今也未曾碰到過相關考題。 但是前幾天,原公司的小美女談到面試過程中就碰到一題: 從A到B,有多條路線,要找出最短路
求一個有向圖G的拓撲序列
題目:已知有向圖G=(V,E),其中V={V1,V2,V3,V4,V5,V6,V7},E={(V1,V2),(V1,V3),(V1,V4),(V2,V5),(V3,V5),(V3,V6),(V4,V6
圖(有向圖,無向圖)的鄰接矩陣表示C++實現(遍歷,拓撲排序,最短路徑,最小生成樹) Implement of digraph and undigraph using adjacency matrix
本文實現了有向圖,無向圖的鄰接矩陣表示,並且實現了從建立到銷燬圖的各種操作。 以及兩種圖的深度優先遍歷,廣度優先遍歷,Dijkstra最短路徑演算法,Prim最小生成樹演算法,有向圖的拓撲排序演算法。 通過一個全域性變數控制當前圖為有向圖還是無向圖。 若為無向圖,則生成的
給定一個m*n的格子或棋盤,問從左上角走到右下角的走法總數(每次只能向右或向下移動一個方格邊長的距離。
比如一個2*3的矩陣, 1 2 3 4 5 6 從1出發走到6,則可能的走法為:1 2 3 6, 1 2 5 6, 1 4 5 6共有三種。 這道題可以看成是深度優先遍歷一顆樹。解法為: public class MatrixTraversal { public s
圖之從一個頂點到其餘各個頂點的最短路徑(有向圖)
目錄 從一個頂點到其餘各個頂點最短路徑的簡介 舉例以及詳細分析 程式碼塊 測試結果 從一個頂點到其餘各個頂點最短路徑的簡介(又名單元最短路徑) 1.定義概覽 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所
DFS的運用(二分圖判定、無向圖的割頂和橋,雙連通分量,有向圖的強連通分量)
part str stack void div prev this 沒有 2-sat 一、dfs框架: 1 vector<int>G[maxn]; //存圖 2 int vis[maxn]; //節點訪問標記 3 void dfs(int u
LeetCode 給定一個 N 叉樹,找到其最大深度。 最大深度是指從根節點到最遠葉子節點的最長路徑上的節點總數
/* // Definition for a Node. class Node { public: int val; vector<Node*> children; Node() {}  
有向圖扇形,角度調整。
clc clear all close all sensingR=18; coverSector=pi/3; Coverlength=50; %x=randi([1 50],1,30); %y=randi([1 50],1,30); % save initDeploy load initDeploy
給定一個正整數n,求出0到n中有幾個數滿足其二進位制表示不包含連續的1
樣例: 輸入:5 輸出:5 0 01 10 100 101滿足,11不滿足。 那麼6144呢? 答案是610,怎麼去計算呢? 思路:查詢從0到n中有多少個數包含連續的1,然後在總數中去掉這些情況,得到
實驗四(建圖,無向圖+鄰接矩陣(BFS,DFS(遞迴+非遞迴)),有向圖+鄰接表(BFS,DFS(遞迴+非遞迴)),拓撲排序)
//Sinhaeng Hhjian #include<bits/stdc++.h> using namespace std; const int N=100; const int MAX=1000; int book[N], cnt; struct node{