計數問題也許可以轉化為矩陣乘法形式
比如若該題沒有不能在一條邊上重複走的條件限制,那麼直接將鄰接矩陣轉化為矩陣乘法即可
故對於計數問題,若可以將 \(n\) 個點表示成 \(n \times n\) 的矩陣,並且可以保證中途轉移物件不會變化,即可用矩陣乘法計數
那麼考慮該題,加入了不能重複在一條邊上走的限制,那麼最簡單的思想就是拆點,並且讓改點遮蔽掉當前方向,但是如果考慮邊,一條無向邊可以拆成兩條有向邊,那拆出來的就比點少很多了,故考慮點邊轉化
那麼只要在起始點加一條超級源邊,同樣矩陣乘法即可統計答案
#include #include #include #define mod 45989
using namespace std;
typedef long long ll;
const int maxn = 50 + 10;
const int maxm = 120 + 10;
struct linkedforwardstar ;
linkedforwardstar link[maxm];
int head[maxn]= ;
int size = 1;
void insert (int u, int v)
int n, m, k;
int st, ed;
struct matrix
matrix operator * (const matrix& p) const
} ;matrix mats, bem;
ll power (int p)
ll ans = 0;
for (int i = head[ed]; i; i = link[i].next)
ans = (ans + mats.a[1][i ^ 1]) % mod;
return ans;
}int getnum ()
int main ()
for (int i = head[st]; i; i = link[i].next)
bem.a[1][i] = 1;
for (int i = 2; i <= size; i ++)
} for (int i = 1; i <= size; i ++)
mats.a[i][i] = 1;
ll ans = power (k);
cout << ans << endl;
return 0;}/*
4 5 3 0 0
0 10 2
0 32 1
3 2*/
SDOI2009 HH的項鍊 題解
題意 給乙個序列,長度為n,再給m個詢問,對每個詢問,輸出這個區間內有多少個不同的數。其實只需要把最後乙個出現的數統計一下就可以了,因為只有最後乙個出現的那個數才是有價值的,之前重複的數可以忽略,由此,演算法的框架就出來了,只需要有cdq的思想把查詢以區間的右端點為關鍵字排序,從前到後,同時用新出現...
洛谷P2151 SDOI2009 HH去散步
hh有個一成不變的習慣,喜歡飯後百步走。所謂百步走,就是散步,就是在一定的時間 內,走過一定的距離。但是同時hh又是個喜歡變化的人,所以他不會立刻沿著剛剛走來的路走回。又因為hh是個喜歡變化的人,所以他每天走過的路徑都不完全一樣,他想知道他究竟有多 少種散步的方法。現在給你學校的地圖 假設每條路的長...
洛谷 P2151 SDOI2009 HH去散步
題目鏈結 思路如果沒有不能走上一條邊的限制,很顯然就是dp。設f i j 表示到達i點走了j步的方案數,移到k點可以表示為f k j 1 f i j 如果有限制的話,可以考慮用邊表示將之前思路中的i變為邊的終點,只要不走同一條邊,轉移還是相同的。但是t 2 30,顯然直接dp是不可行的,這是機智的題...