[CQOI2018] Social Network

topic background

In today's society, watching friends' news on social networks has become a part of many people's lives. Usually, after a user posts a message (such as Weibo, Status, Tweet, etc.) on a social network, his friends can also see the message and possibly forward it. Forwarded messages can continue to be forwarded and spread throughout the social network.

Topic description

In an experimental small-scale social network we found that sometimes a popular message ends up being retweeted by everyone. To study the process by which this phenomenon occurs, we wish to count all possible forwarding paths for a message. For the convenience of programming, we set the initial message sender number to 1, and the other user numbers increase sequentially.

All friend relationships on the social network are known, that is to say, for users A and B, we know that user A can see the messages sent by user B. Note that there may be a one-way friendship relationship, that is, lA can see B's messages, but B cannot see A's messages.

Another assumption is that if a user sees multiple friends of his retweeting the same message, he will only choose to retweet from one of them, at most once. Retweets from different friends are considered different situations.

If friends are represented by arrows, the diagram below shows all possible scenarios for message forwarding in a social network. (The initial message was sent by user 1, and the bold arrow indicates a message forwarding)

Input and output format

Input format:

 

The first line of the input file is a positive integer n, which represents the number of users in the social network; the second line is a positive integer m, which represents the number of friends in the social network.

The next m lines, each line is two space-separated integers  a_i a i ​ and  b_i b i ​, representing a group of friend relationships, that is, the user  a_i a i​ can see   the messages sent user b_i b i ​.

 

Output format:

 

The output file consists of one line, which is the remainder of dividing the number of all possible forwarding paths for a message by 10007.

 

Input and output example

Input Example #1:  Copy
4
7
2 1
3 1
1 3
2 3
3 2
4 3
4 2
Output Sample #1:  Copy
6

illustrate

For 30% of the data,  1≤n≤10 1 n 1 0

For 100% data,  1≤n≤250, 1≤a_i,b_i≤n, 1≤m≤n(n-1) 1 n 2 5 0 , 1 a i ​, b i ​≤ n , 1 m n ( n 1 )

 

   Bare directed graph spanning tree count issue #2333.

    But today I got a new skill (or it was too zzy in the past), that is, Gaussian elimination under mod number directly converts all divisions into multiplication inverses (Isn’t this a noip knowledge point? 233 Why didn’t I think of it before) , without any tossing and reducing. . . . . .

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int ha = 10007;
const int maxn=255;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline int ksm(int x,int y){ int an=1; for(;y;y>>=1,x=x*x%ha) if(y&1) an=an*x%ha; return an;}
int n,m,a[maxn][maxn],id[maxn],ans=1,inv,M;

inline void xy(){
	for(int i=2;i<=n;i++){
		if(!a[i][i]){
			years=ha-years;
			for(int j=i+1;j<=n;j++) if(a[j][i]){
				for(int k=i;k<=n;k++) swap(a[i][k],a[j][k]);
				break;
			}
		}
		if(!a[i][i]){ ans=0; break;}
		ans=ans*a[i][i]%ha;
		
		inv=ksm(a[i][i],ha-2);
		for(int j=i+1;j<=n;j++) if(a[j][i]){
			M=inv*a[j][i]%ha;
			for(int k=i;k<=n;k++) a[j][k]=add(a[j][k],ha-a[i][k]*M%ha);
		}
	}
}

int main(){
	int uu, vv;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&uu,&vv);
		a [vv] [uu] ++, id [uu] ++;
	}
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	        if(i==j) a[i][i]=id[i];
	        else a [i] [j] = ha-a [i] [j];
	xy();
	printf("%d\n",ans);
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324726956&siteId=291194637