[CQOI2018] 社交網絡

Description

當今社會,在社交網絡上看朋友的消息已經成爲許多人生活的一部分。通常,一個用戶在社交網絡上發佈一條消息
(例如微博、狀態、Tweet等)後,他的好友們也可以看見這條消息,並可能轉發。轉發的消息還可以繼續被人轉
發,進而擴散到整個社交網絡中。在一個實驗性的小規模社交網絡中我們發現,有時一條熱門消息最終會被所有人
轉發。爲了研究這一現象發生的過程,我們希望計算一條消息所有可能的轉發途徑有多少種。爲了編程方便,我們
將初始消息發送者編號爲1,其他用戶編號依次遞增。該社交網絡上的所有好友關係是已知的,也就是說對於A、B
兩個用戶,我們知道A用戶可以看到B用戶發送的消息。注意可能存在單向的好友關係,即A能看到B的消息,但B不
能看到A的消息。
還有一個假設是,如果某用戶看到他的多個好友轉發了同一條消息,他只會選擇從其中一個轉發,最多轉發一次消
息。從不同好友的轉發,被視爲不同的情況。
如果用箭頭表示好友關係,下圖展示了某個社交網絡中消息轉發的所有可能情況。
初始消息是用戶1發送的,加粗箭頭表示一次消息轉發

Input

輸入文件第一行,爲一個正整數n,表示社交網絡中的用戶數:
第二行爲一個正整數m.表示社交網絡中的好友關係數目。
接下來m行,每行爲兩個空格分隔的整數ai和bi,表示一組好友關係,即用戶ai可以看到用戶bi發送的消息。
1≤n≤250,1≤ai,bi≤n,1≤m≤n(n-1)

Output

輸出文件共一行,爲一條消息所有可能的轉發途徑的數量,除以1 0007所得的餘數。

Sample Input

4
7
2 1
3 1
1 3
2 3
3 2
4 3
4 2

Sample Output

6

Solution

一眼矩陣樹定理模板題,省選出這個真的。

用出度矩陣和臨接矩陣相減構造基爾霍夫矩陣,求矩陣行列式。

Code

#include <iostream>
#include <cstdio>

#define R register
#define ll long long

using namespace std;

namespace Dntcry
{
	inline int read()
	{
		R int a = 0, b = 1; R char c = getchar();
		for(; c < '0'|| c > '9'; c = getchar()) (c == '-') ? b = -1 : 0;
		for(; c >= '0' && c <= '9'; c = getchar()) a = (a << 1) + (a << 3) + c - '0';
		return a * b;
	}
	const int Mod = 10007;
	int n, m, Map[310][310], inv[10010], Ans;
	int Guass()
	{
		R int res = 1;
		for(R int i = 2, j; i <= n; i++)
		{
			for(j = i; !Map[j][i]; j++) ;
			if(j > n) continue ;
			if(j != i) 
			{
				res = Mod - res;				
				for(R int k = i; k <= n; k++) swap(Map[i][k], Map[j][k]);
			}
			for(j = i + 1; j <= n; j++)
				if(Map[j][i])
				{
					R int tmp = Map[j][i] * inv[Map[i][i]] % Mod;
					for(R int k = i; k <= n; k++)
						Map[j][k] = (Map[j][k] - tmp * Map[i][k] % Mod + Mod) % Mod;
				}
		}
		for(R int i = 2; i <= n; i++) res = res * max(Map[i][i], 1) % Mod;
		return res;
	}
	int Main()
	{
		n = read(), m = read();
		inv[0] = inv[1] = 1;
		for(R int i = 2; i < 10010; i++) inv[i] = (Mod - Mod / i) * inv[Mod % i] % Mod;
		for(R int i = 1, u, v; i <= m; i++)
		{
			v = read(), u = read();
			Map[v][v] = (Map[v][v] + 1) % Mod;
			Map[u][v] = (Map[u][v] - 1) % Mod;
		}
		Ans = Guass();
		printf("%d\n", Ans);
		return 0;
	}
}
int main() { return Dntcry :: Main(); }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章