CQOI2018 社交网络

题目背景

当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分。通常,一个用户在社交网络上发布一条消息(例如微博、状态、Tweet等) 后,他的好友们也可以看见这条消息,并可能转发。转发的消息还可以继续被人转发,进而扩散到整个社交网络中。

题目描述

在一个实验性的小规模社交网络中我们发现,有时一条热门消息最终会被所有人转发。为了研究这一现象发生的过程,我们希望计算一条消息所有可能的转发途径有多少种。为了编程方便,我们将初始消息发送者编号为1,其他用户编号依次递增。

该社交网络上的所有好友关系是已知的,也就是说对于A、B 两个用户,我们知道A 用户可以看到B 用户发送的消息。注意可能存在单向的好友关系,即lA 能看到B 的消息,但B 不能看到A 的消息。

还有一个假设是,如果某用户看到他的多个好友转发了同一条消息,他只会选择从其中一个转发,最多转发一次消息。从不同好友的转发,被视为不同的情况。

如果用箭头表示好友关系,下图展示了某个社交网络中消息转发的所有可能情况。 (初始消息是用户1发送的,加粗箭头表示一次消息转发)

说明

对于30%的数据,$1≤n≤10$

对于100%的数据,$1≤n≤250, 1≤a_i,b_i≤n, 1≤m≤n(n-1)$

题解

求的其实就是有向图中以1为根的生成树数量。Matrix Tree定理裸题。

入度矩阵对应的外向树,出度矩阵对应着内向树(都是指向父亲的边的事是出度或者入度)无根树就是两条有向边都加上

有向树必须删掉根所在的那一行和一列,无根树可以任意

然后对于这n−1阶的矩阵求一个行列式就行了,也叫主子式

#include<bits/stdc++.h>
using namespace std; void read(int&x) {
x=0;int w=1;char ch=getchar();
for(; !isdigit(ch); ch=getchar())if(ch=='-') w=-w;
for(; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
x*=w;
} const int mod=1e4+7;
int fpow(int x,int k) {
int ans=1;
for(; k; k>>=1,x=x*x%mod)
if(k&1) ans=ans*x%mod;
return ans;
} int A[255][255];
int gauss(int n) {
int p=1;
for(int i=1; i<n; i++) {
int k=i;
for(int j=i+1; j<=n; j++)
if(A[j][i]>A[k][i]) k=j;
if(k!=i) swap(A[k],A[i]),p*=-1;
if(!A[i][i])
return 0;
int inv=fpow(A[i][i],mod-2);
for(int j=i+1; j<=n; j++) {
int coef=A[j][i]*inv%mod;
for(int k=i; k<=n; k++) A[j][k]=(A[j][k]+mod-coef*A[i][k]%mod)%mod;
}
}
if(p<0) p+=mod;
for(int i=1; i<=n; i++) p=p*A[i][i]%mod;
return p;
}
int main() {
int n,m;
read(n),read(m);
for(int x,y; m--;) {
read(x),read(y); // y->x
--A[y-1][x-1],++A[x-1][x-1];
}
for(int i=0; i<n; i++)for(int j=0; j<n; j++)
if(A[i][j]<0) A[i][j]+=mod;
printf("%d\n",gauss(n-1));
return 0;
}

快速求解行列式

求行列式的一般方法是把矩阵通过基础行变换或者列变换把矩阵消成一个上三角矩阵,然后对角线上的值相乘即可

具体的变换是

  1. 行列交换,行列式不变 就是ai,j变成aj,i(但是一般用不上这个)
  2. 行列式一行的因子可以提出 就是一行都除k,求完这个行列式后再乘上k
  3. 两行互换,行列式反号
  4. 将一行的倍数加到另一行上,行列式不变

好像写的话只需要34就够了

黑暗前的幻想乡

幽香上台以后,第一项措施就是要修建幻想乡的公路。幻想乡有 N 个城市,之间原来没有任何路。幽香向选民承诺要减税,所以她打算只修 N- 1 条路将

这些城市连接起来。但是幻想乡有正好 N- 1 个建筑公司,每个建筑公司都想在修路的过程中获得一些好处。

虽然这些建筑公司在选举前没有给幽香钱,幽香还是打算和他们搞好关系,因为她还指望他们帮她建墙。所以她打算让每个建筑公司都负责一条路来修。

每个建筑公司都告诉了幽香自己有能力负责修建的路是哪些城市之间的。所以幽香打算选择 N-1 条能够连接幻想乡所有城市的边,然后每条边都交给一个能够负责该边的建筑公司修建,并且每个建筑公司都恰好修一条边。

幽香现在想要知道一共有多少种可能的方案呢?两个方案不同当且仅当它们要么修的边的集合不同,要么边的分配方式不同。

N<=17

jklover的题解

如果把所有出现的边都加上,直接算生成树个数,可能会包括了有某些公司没有用边的情况.

于是减去 1 个公司不修路,其他公司随便修的方案数.再加上 2 个公司不修路的方案数…

二进制大力枚举每个公司的边考不考虑,用矩阵树定理算方案数,乘上容斥系数即可.

时间复杂度 O(2n⋅n3) .

#include<bits/stdc++.h>
using namespace std;
template<class T> T read(){
T x=0,w=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*w;
}
template<class T> T read(T&x){
return x=read<T>();
}
#define co const
#define il inline
typedef long long LL; co int mod=1000000000+7;
il int add(int a,int b){
return (a+=b)>=mod?a-mod:a;
}
il int mul(int a,int b){
return (LL)a*b%mod;
}
il int fpow(int a,int b){
int ans=1;
for(;b;b>>=1,a=mul(a,a))
if(b&1) ans=mul(ans,a);
return ans;
} co int N=17;
int n;
typedef pair<int,int> edge;
vector<edge> e[N];
int A[N][N]; int gauss(){
int ans=1;
for(int i=1;i<n;++i){
if(!A[i][i]){
for(int j=i+1;j<n;++j)if(A[j][i]){
swap(A[i],A[j]),ans=mul(ans,mod-1);
break;
}
}
if(!A[i][i]) return 0;
ans=mul(ans,A[i][i]);
for(int j=i+1;j<n;++j){
int alph=mul(mod-A[j][i],fpow(A[i][i],mod-2));
for(int k=i;k<n;++k) A[j][k]=add(A[j][k],mul(alph,A[i][k]));
}
}
return ans;
}
int main(){
read(n);
for(int i=0;i<n-1;++i)
for(int m=read<int>();m--;)
e[i].push_back((edge){read<int>()-1,read<int>()-1}); int ans=0;
for(int s=0;s<1<<(n-1);++s){
memset(A,0,sizeof A);
for(int i=0;i<n-1;++i)if(~s>>i&1){
for(int j=0;j<(int)e[i].size();++j){
int u=e[i][j].first,v=e[i][j].second;
++A[u][u],++A[v][v];
A[u][v]=add(A[u][v],mod-1),A[v][u]=add(A[v][u],mod-1);
}
}
ans=add(ans,__builtin_popcount(s)&1?mod-gauss():gauss());
}
printf("%d\n",ans);
return 0;
}

2019年9月23日10:39:49,LOJ又炸了。

LG4455 【[CQOI2018]社交网络】的更多相关文章

  1. [HEOI2015]小Z的房间 && [CQOI2018]社交网络

    今天看了一下矩阵树定理,然后学了一下\(O(n ^ 3)\)的方法求行列式. 哦对了,所有的证明我都没看-- 这位大佬讲的好呀: [学习笔记]高斯消元.行列式.Matrix-Tree 矩阵树定理 关于 ...

  2. BZOJ5297 CQOI2018 社交网络 【矩阵树定理Matrix-Tree】

    BZOJ5297 CQOI2018 社交网络 Description 当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分.通常,一个用户在社交网络上发布一条消息(例如微博.状态.Tweet等 ...

  3. P4455 [CQOI2018]社交网络(矩阵树定理)

    题目 P4455 [CQOI2018]社交网络 \(CQOI\)的题都这么裸的吗?? 做法 有向图,指向叶子方向 \(D^{out}(G)-A(G)\) 至于证明嘛,反正也就四个定理,先挖个坑,省选后 ...

  4. bzoj 5297: [Cqoi2018]社交网络

    Description 当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分.通常,一个用户在社交网络上发布一条消息 (例如微博.状态.Tweet等)后,他的好友们也可以看见这条消息,并可能转 ...

  5. [CQOI2018] 社交网络

    题目背景 当今社会,在社交网络上看朋友的消息已经成为许多人生活的一部分.通常,一个用户在社交网络上发布一条消息(例如微博.状态.Tweet等) 后,他的好友们也可以看见这条消息,并可能转发.转发的消息 ...

  6. P4455 [CQOI2018]社交网络

    这个题仔细一看就是生成树计数,但是我这个记性是真的差,早就忘了.复习了一下高斯消元,然后这个题就是很裸的题了. ps:高斯消元解行列式的时候要取反. 题干: 题目背景 当今社会,在社交网络上看朋友的消 ...

  7. BZOJ5297 CQOI2018社交网络(矩阵树定理)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  8. [BZOJ5297][CQOI2018]社交网络

    bzoj luogu sol 就是求以\(1\)为根的生成树的数量. 直接矩阵树定理. code #include<cstdio> #include<algorithm> #i ...

  9. BZOJ5297 [Cqoi2018]社交网络 【矩阵树定理】

    题目链接 BZOJ5297 题解 最近这玩意这么那么火 这题要用到有向图的矩阵树定理 主对角线上对应入度 剩余位置如果有边则为\(-1\),不然为\(0\) \(M_{i,i}\)即为以\(i\)为根 ...

随机推荐

  1. (转)TeamViewer三种许可证的区别是什么?

    xu言: 这几天在使用teamview对它的许可证做了一些了解,看到这个好像是官方的写的挺不错.留作收藏 PS:https://www.uret.in/  顺便也发现了一个不错的网站 很多想要购买Te ...

  2. 4-3 atom订阅源

    部分章节还没有实做练习. 网上购买了安道的Rails指南中文版.联系了这个作者问了一个问题Rails5的翻译问题. try(), 判断是否存在,不存在的话返回nil.例子:pasting @perso ...

  3. UVA-10026 Shoemaker's Problem (贪心)

    题目大意:一个鞋匠,有n只鞋要修,修某只鞋的时间ti已知,某只鞋晚修一天要交的罚款fi也已知.现在让找个修鞋顺序使得罚款最少. 题目分析:本来想水一下这道题,没想到真的AC啦.后来又查的题解,找的解释 ...

  4. sublime 个人心得

    sublime 3快捷键: (1) Ctrl+O(Command+O)可以实现头文件和源文件之间的快速切换 (2) 双击可选中光标所在单词,三击可选中光标所在行(等同于Ctrl+L(Command+L ...

  5. sql去重;同一条数据出现多条取一条的sql语句

    理论上相同数据个别字段值不同重复问题: 1.某字段重复,其他字段值不同时,按重复字段分组只取一条的sql语句(eg:相同的数据某个字段值有差别导致存储两条或多条无意义重复数据的情况)select s. ...

  6. .net 中struct(结构)和class(类)的区别

    1.struct 结构与class(类)的区别 1)struct是值类型,class是对象类型 2)struct不能被继承,class可以被继承 3)struct默认访问权限是public,而clas ...

  7. linux processes identifiers

    Linux, like all Unix uses user and group identifiers to check for access rights to files and images ...

  8. Automatic Login Using sshpass

    #! /bin/bash user=root password=12345678 remote_ip=192.168.3.140 sshpass -p $password ssh $user@$rem ...

  9. web 攻击靶机解题过程

    sql注入靶机攻击过程请参考 https://pentesterlab.com/exercises/from_sqli_to_shell/course http://www.sohu.com/a/12 ...

  10. 6.pragma pack

    下面两个结构体 struct One { double d; char c; int i; } struct Two { char c; double d; int i; } 在#pragma pac ...