刨幺单机版下载

bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥

小说:刨幺单机版下载作者:陵扁文建更新时间:2018-08-22字数:61721

直到今天,他无意中亲眼看到了,亲眼听到了汉人奴隶们的悲惨,就仿佛迎头一棍,将他打醒了。

注册送30的捕鱼游戏

“呃什么呃,快点,拉床过来。你不是挺有力气的么?”小舞有些不耐的催促道。
“不!不是他,是安禄山的三子安庆和,副将是张忠志。”,“呵呵!一个乳臭未干的小子,当真是送上门来的肥羊。”

随手一招,一颗赤红色珠子从蜥蜴人体内飞出落入手中,查看一下果然有精纯的火焰能量但是却极为狂暴,看样子长期生活在熔岩当中,导致这些蜥蜴人体内类似魔核一样的珠子里面的能量比起一般火属性魔兽都要狂暴。

4596: [Shoi2016]黑暗前的幻想乡

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 559  Solved: 325
[Submit][Status][Discuss]

Description

四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖
怪涌入了幻想乡,扰乱了幻想乡昔日的秩序。但是幻想乡的建制派妖怪(人类)
博丽灵梦和八云紫等人整日高谈所有妖怪平等,幻想乡多元化等等,对于幻想乡
目前面临的种种大问题却给不出合适的解决方案。
风间幽香是幻想乡里少有的意识到了问题的严重性的大妖怪。她这次勇敢的
站了出来参加幻想乡大选。提出包括在幻想乡边境建墙(并让人类出钱),大力
开展基础设施建设挽回失业率等一系列方案,成为了大选年出人意料的黑马并顺
利的当上了幻想乡的大统领。
幽香上台以后,第一项措施就是要修建幻想乡的公路。幻想乡有 N 个城市,
之间原来没有任何路。幽香向选民承诺要减税,所以她打算只修 N- 1 条路将
这些城市连接起来。但是幻想乡有正好 N- 1 个建筑公司,每个建筑公司都想
在修路的过程中获得一些好处。
虽然这些建筑公司在选举前没有给幽香钱,幽香还是打算和他们搞好关系,
因为她还指望他们帮她建墙。所以她打算让每个建筑公司都负责一条路来修。
每个建筑公司都告诉了幽香自己有能力负责修建的路是哪些城市之间的。所
以幽香打算选择 N-1 条能够连接幻想乡所有城市的边,然后每条边都交给一
个能够负责该边的建筑公司修建,并且每个建筑公司都恰好修一条边。
幽香现在想要知道一共有多少种可能的方案呢?两个方案不同当且仅当它
们要么修的边的集合不同,要么边的分配方式不同。

Input

第一行包含一个正整数 N(N<=17), 表示城市个数。
接下来 N-1 行,其中第 i行表示第 i个建筑公司可以修建的路的列表:
以一个非负数mi 开头,表示其可以修建 mi 条路,接下来有mi 对数,
每对数表示一条边的两个端点。其中不会出现重复的边,也不会出现自环。

Output

仅一行一个整数,表示所有可能的方案数对 10^9 + 7 取模的结果。

Sample Input

4
2 3 2 4 2
5 2 1 3 1 3 2 4 1 4 3
4 2 1 3 2 4 1 4 2

Sample Output

17

HINT

Source

By 佚名上传

 

容斥一下让哪几个公司来修就可以了,然后每次矩阵树定理求一下方案树就可以了。

这里是直接高斯消元的,没有辗转相除的形式,但是好像矩阵树是保证还是桌面回事,不需要的。

 

 1 #pragma GCC optimize(2)
 2 #pragma G++ optimize(2)
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 
 9 #define ll long long
10 #define N 22
11 #define mod 1000000007
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)){if(ch=="-")f=-1;ch=getchar();}
17     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-"0";ch=getchar();}
18     return x*f;
19 }
20 
21 int n;
22 int a[N][N],f[N][N],ans;
23 int cnt,hed[N];
24 struct Node
25 {
26     int x,y,nxt;
27 }e[10007];
28 
29 void add(int u,int x,int y)
30 {
31     e[++cnt].x=x;
32     e[cnt].y=y;
33     e[cnt].nxt=hed[u];
34     hed[u]=cnt;
35 }
36 int cal(int num)//矩阵树定理是每个点的度,若x-y有边则x,y -1,y,x -1然后消去一行,下三角消元
37 {
38     //这里好处是num为n-1了,已经减去一行了。
39     for (int i=1;i<=num;i++)
40         for (int j=1;j<=num;j++)
41             a[i][j]=f[i][j];
42     int ans=1;
43     for (int i=1;i<=num;i++)
44     {
45         for (int j=i+1;j<=n;j++)
46             while(a[j][i])
47             {
48                 int t=a[i][i]/a[j][i];
49                 for (int k=i;k<=n;k++)a[i][k]=(a[i][k]-(ll)a[j][k]*t%mod)%mod;
50                 for (int k=i;k<=n;k++)swap(a[i][k],a[j][k]);
51                 ans=-ans;//ans去反是因为斜对角线上负数的个数
52             }
53         if(!a[i][i])return 0;
54         ans=(ll)ans*a[i][i]%mod;
55     }
56     return ans;
57 }
58 void dfs(int x,int y)
59 {
60     if (x==n)//就n-1个人
61     {
62         (ans+=y*cal(n-1))%=mod;
63         return;
64     }
65     dfs(x+1,y);
66 
67     for (int i=hed[x];i!=-1;i=e[i].nxt)
68     {
69         int u=e[i].x,v=e[i].y;
70         f[u][u]--,f[v][v]--,f[u][v]++,f[v][u]++;
71     }
72     dfs(x+1,-y);
73     for (int i=hed[x];i!=-1;i=e[i].nxt)
74     {
75         int u=e[i].x,v=e[i].y;
76         f[u][u]++,f[v][v]++,f[u][v]--,f[v][u]--;
77     }
78 }
79 int main()
80 {
81     memset(hed,-1,sizeof(hed));
82     n=read();
83     for (int i=1;i<n;i++)
84     {
85         int number=read();
86         for (int j=1;j<=number;j++)
87         {
88             int x=read(),y=read();
89             add(i,x,y);
90             f[x][x]++,f[y][y]++,f[x][y]--,f[y][x]--;
91         }
92     }
93     dfs(1,1);
94     printf("%d
",(ans%mod+mod)%mod);
95 }

 

编辑:纯成

发布:2018-08-22 00:53:56

当前文章:http://www.leetaemin.cn/play/pyd2m72s7d.html

钱宝注册送28结束了吗 注册送彩金的彩票ap 彩金风暴亚洲原创50p 连环夺宝注册送96元体验金 88老虎机官网注册送19元 九五至尊娱乐注册送94元现金 注册不用存款送75元彩金 博彩开户送27元彩金

Pt老虎机注册送45元 免费注册送51元现金 救援彩金 明升娱乐场反水 财神娱乐场线上赌博 AB国际博彩现金开护炸金花发底牌技巧视频 虎博城娱乐官网 赌场平台开户送彩金

我要说两句: (0人参与)

发布