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. Myeclipse2016安装Aptana

    Myeclipse2016安装Aptana 想装个Aptana,装了半天,网上说的什么links方式啊,在线方式啊,都是什么的浮云. 所以自己来写个安装教程. 一.Aptana简要介绍 Aptana有 ...

  2. Android 7.0真实上手体验

    Android 7.0真实上手体验 Android 7.0的首个开发者预览版发布了,支持的设备只有Nexus6.Nexus 5X.Nexus 6P.Nexus 9.Nexus Player.Pixel ...

  3. FasfDFS intall nginx with image filter

    centOS7 x64 1. install gd-devel 2. ./configure --prefix=/usr/local/nginx --with-http_image_filter_mo ...

  4. C++中的this指针

    1.关于this指针的一个精典回答: 当你进入一个房子后,你可以看见桌子.椅子.地板等,但是房子你是看不到全貌了.对于一个类的实例来说,你可以看到它的成员函数.成员变量,但是实例本身呢?this是一个 ...

  5. WaitForMultipleObjects用法详解

    本文转载于:http://blog.csdn.net/sac761/article/details/52456385 WaitForMultipleObjects是Windows中的一个功能非常强大的 ...

  6. _beginthreadex()和CreateThread()的区别

    在本例子中我们使用——beginThreadex这个函数,它和createThread的区别是: 为了方便管理,我么在使用该函数的时候可以把它的线程函数作为类成员,这也就需要在类中把该函数变成静态函数 ...

  7. OAF 获取页面路径

    --模糊查询某个页面 SELECT * FROM JDR_PATHS jp WHERE JP.PATH_NAME LIKE '%XXXX%'; --精确的查找过程 -- DocID --参数通过关于此 ...

  8. (转)RocketMQ源码学习--消息存储篇

    http://www.tuicool.com/articles/umQfMzA 1.序言 今天来和大家探讨一下RocketMQ在消息存储方面所作出的努力,在介绍RocketMQ的存储模型之前,可以先探 ...

  9. js中JSON.stringify用于自定义的类

    参考:http://stackoverflow.com/questions/7356694/how-to-json-stringify-a-user-defined-class-in-javascri ...

  10. 超详细:Python(wordcloud+jieba)生成中文词云图

    # coding: utf-8 import jieba from scipy.misc import imread # 这是一个处理图像的函数 from wordcloud import WordC ...