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. php 7.2 安装 mcrypt 扩展: mcrypt 扩展从 php 7.1.0 开始废弃;自 php 7.2.0 起,会移到 pecl

    升级 php 7.2 后,使用微信提供的加解密代码时,提示 call to undefined function mcrypt_module_open() :大脑疯狂运转1秒钟后,得出结论:php 7 ...

  2. python模块——hashlib模块(简单文件摘要算法实现)

    #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = "loki" # Usage: hashlib模块 import ...

  3. 基于DOMContentLoaded实现文档加载完成后执行的方法

    我们有时可能需要一些在页面加载完成之后执行的方法,其实js原生就提供了onload方法,所以我们最简单的办法就是直接给onload赋值一个函数,在页面加载完成之后就会自动执行 widnow.onloa ...

  4. python-day36--并发编程之多线程

    十三.死锁.递归锁 1.所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永 ...

  5. mysql导出导入数据库表

    1.下载数据库 mysqldump db_name  -h 192.168.5.162 -uroot -p > /var/www/db_name.sql(这个可以自定义) 2,下载数据库中的某个 ...

  6. hdu 1258

    Sum It Up Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  7. OC MRC之set方法内存管理(代码分析)

    // // main.m // 03-set方法的内存管理 // // Created by apple on 13-8-9. // Copyright (c) 2013年 itcast. All r ...

  8. 【转】json与jsonp区别浅析(json才是目的,jsonp只是手段)

    一言以蔽之,json返回的是一串数据:而jsonp返回的是脚本代码(包含一个函数调用): JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展 ...

  9. form数据请求参数格式

    请求后台参数格式问题 当请求后台传递参数时,有多中类型,而每一种都需要前后台进行配合,而这有时候会很简单,有时候却十分困难,记录一下,以备后期深究 数据 后台需要的数据 form表单 嵌套数据,第二层 ...

  10. bzoj3332

    题解: 首先只有存在的路有可能有值 然后在存储矩阵的同时对于本来就有边的情况直接存下来这条边的值 然后跑一次最大生成树 在最大生成树的同时就可以求出矩阵的信息. 代码: #include<bit ...