这个题真的折磨了我超久的。全网几乎搜不到一个详细的题解,俺来写写吧。

题意:给你一个无自环无重边的连通无向图,求它邻接矩阵的行列式的值。

\(n\le 2*10^5,n-1\le m \le n+50\)

行列式定义,取一排列 \(p\),算它逆序对奇偶,再算 \(a_{i,p_i}\) 的乘积,乘起来,加起来是吧。经典的 \(i->p_i\) ,逆序对奇偶其实和“点数-环数”相等的,这个不难证。

发现这个 \(i->p_i\) 刚好能对应到图上。你不是要一堆 \(a_{i,p_i}\) 乘起来嘛,然后 \(a\) 又是原图的邻接矩阵。

所以一个排列 \(p\) 的权值不为 \(0\) ,应当是它连出来之后的若干个环都在图上出现,此处有特殊情况,就是“二元环”,退化成了一个边。

换句话,就是用若干环或边,覆盖所有点。

接下来考虑怎么利用 \(m\le n+50\) 以及上面的性质,对整个图进行一个改造。

用一些度数小的点入手,这样它们被覆盖的方法是很固定的。

Step1.度数为 \(1\) 的点

只能把这个点 \(u\) 和与它相连的点 \(v\) 覆盖了。也就是 \(p_u=v,p_v=u\)

然后可以把这俩点删了。

所以下面的讨论中,所有点度数大于等于2!

Step2. 度数为 \(2\) 的点

这一步就很 magic 了。

结论一:考虑四个相连的度数为 \(2\) 的点,将它们删去,并把两端的点连上,行列式值不变。

证明就是分类讨论。

设四个点分别为 \(u_1,u_2,u_3,u_4\),\(u_1\) 左的点为 \(l\) ,\(u_4\) 右的点为 \(r\) 。

有如下三种情况:

  1. 选择 \((u_1,u_2),(u_3,u_4)\) ,系数为正,在新图里,这等价于不选 \((l,r)\) 这个边。

  2. 选择 \((l,u_1),(u_2,u_3),(u_4,r)\) 系数为负,在新图里,这等价于选了 \((l,r)\) 这个边。

  3. 整体被吃进一个环里。在新图里还是被吃。

综上,新图与原图是等价的。

但这里有一些 corner case,就是 \(l=r\) 要尤其小心。我们发现,比如说原来有 \(5\) 个二度点,删成只剩 \(1\) 个,这里就连出重边了,这是不好的。

所以我们的方法是,对于一串二度点,一直 -=4,直到 \(\le 5\) 为止。

我们现在得到了一个新图。

结论二:此图点数是 \(O(m-n)\) 级别,此处 \(n,m\) 是原题给出的 \(n,m\)。

首先,前面的那些操作有没有影响 \(m-n\) ?发现这个一定是变小了的。

假装我们把一串二度点删掉,把两端连上,形成一个度数全部 \(>2\) 的图。这个过程没有影响 \(m-n\) 。

设此时图点数 \(N\) ,边数 \(M\) ,由于度数之和大于等于 \(3N\) ,\(M\) 就大于等于 \(3N/2\) ,则 \(N/2\le M-N\le m-n\)

极限情况就是 \(N=2(m-n),M=3(m-n)\) 了。

再考虑二度点,相当于有 \(5M\) 个二度点。

所以我们的图极限情况下 \(17(m-n)\le 850\) 个点,而且卡不满。

事实上原题数据开 \(300\) 都是能过的,感觉可以证到一个更低的界?

直接对着这个图求行列式。这道题我们就做完了。

复杂度是 \(O(n\log n+C(m-n)^3)\) 其中 \(C=17^3\) 。为什么有 \(\log\) 呢,我为了方便删边用 set 存图(

代码实现时要注意的问题:

  1. 删一度点以 bfs 的方式来删,直接 dfs 会有神秘错误。

  2. 本人是从 \(>2\) 的度数的点开始找 \(2\) 度点。这样会忽略一种情况:整个图就是个环,需要特判

  3. 再说一遍:删二度点时删到 \(\le 5\) 为止。

#include<bits/stdc++.h>
using namespace std;
int n,m,d[201000];
bool vis[200100];
set<int>g[200100];
int ak;
const int mod=998244353;
queue<int>q;
void dk(int x){
for(int v:g[x])if(!vis[v]){
if(d[x]==1){puts("0");exit(0);}
d[x]--;if(d[x]==1)q.push(x);
}
}
void del(int x){
if(vis[x])return;
int u=-1;
for(int v:g[x])if(!vis[v])u=v;
if(u==-1){puts("0");exit(0);}
vis[x]=vis[u]=1,ak=-ak;
dk(x),dk(u);
}
bool vp[201000];
int id[201000];
int a[1010][1010];
int N;
void del(int &a,int b){
(a-=b)%=mod;
(a+=mod)%=mod;
}
vector<int>oo;
int main(){
scanf("%d%d",&n,&m);
ak=1;
for(int i=0,u,v;i<m;i++)scanf("%d%d",&u,&v),g[u].insert(v),g[v].insert(u),d[u]++,d[v]++;
for(int i=1;i<=n;i++)if(d[i]==1)q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
del(u);
}
bool fl=1;int ap=0;
for(int i=1;i<=n;i++)if(!vis[i])fl&=(d[i]==2),ap++;
if(fl){
if(!ap)return printf("%d",(ak+mod)%mod),0;
int su=-2;
if(!(ap&1))su+=(((ap/2)&1)?-2:2);
return printf("%d",(su*ak*((ap&1)?-1:1)%mod+mod)%mod),0;
}
for(int i=1;i<=n;i++)if(!vis[i]&&d[i]>2){
vector<int>nmd;
for(int v:g[i])if(!vis[v]&&d[v]==2&&!vp[v])nmd.push_back(v);
for(int v:nmd)if(!vp[v]){
oo.clear();
oo.push_back(v);
int u=v,pr=i;
int D;
while(1){
int nx;
for(int op:g[u])if(pr!=op)nx=op;
if(d[nx]==2)pr=u,u=nx,oo.push_back(u);
else{D=nx;break;}
}
for(int nm:oo)vp[nm]=1;
int sz=oo.size();
if(sz>5){
int O=sz%4;
if(O<=1)O+=4;
for(int ii=O;ii<sz;ii++)vis[oo[ii]]=1;
g[oo[O-1]].erase(oo[O]);
g[oo[O-1]].insert(D);
g[D].erase(oo[sz-1]),g[D].insert(oo[O-1]);
}
}
}
for(int i=1;i<=n;i++)if(!vis[i])id[i]=++N;
for(int i=1;i<=n;i++)if(id[i])for(int v:g[i])if(id[v])a[id[i]][id[v]]++;
for(int i=1;i<=N;i++){
for(int j=i+1;j<=N;j++){
while(a[i][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<=N;k++)del(a[j][k],1ll*t*a[i][k]%mod);
swap(a[i],a[j]);ak=-ak;
}
swap(a[i],a[j]),ak=-ak;
}
}
for(int i=1;i<=N;i++)ak=1ll*ak*a[i][i]%mod;
return printf("%d",(ak%mod+mod)%mod),0;
}

URAL2127 Determinant of a Graph 题解的更多相关文章

  1. POJ 1737 Connected Graph 题解(未完成)

    Connected Graph Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3156   Accepted: 1533 D ...

  2. CF1581B Diameter of Graph 题解

    Content \(\textsf{CQXYM}\) 想要构造一个包含 \(n\) 个点和 \(m\) 条边的无向连通图,并且他希望这个图满足下列条件: 该图中不存在重边和自环.也就是说,一条边应该连 ...

  3. [Leetcode Week3]Clone Graph

    Clone Graph题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/clone-graph/description/ Description Clon ...

  4. 【Lintcode】137.Clone Graph

    题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. ...

  5. CodeForces 715B Complete The Graph 特殊的dijkstra

    Complete The Graph 题解: 比较特殊的dij的题目. dis[x][y] 代表的是用了x条特殊边, y点的距离是多少. 然后我们通过dij更新dis数组. 然后在跑的时候,把特殊边都 ...

  6. 算法与数据结构基础 - 图(Graph)

    图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...

  7. ACM - 最短路 - CodeForces 295B Greg and Graph

    CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...

  8. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  9. [LeetCode]题解(python):133-Clone Graph

    题目来源: https://leetcode.com/problems/clone-graph/ 题意分析: 克隆一个无向图.每个节点包括一个数值和它的邻居. 题目思路: 直接深度拷贝. 代码(pyt ...

  10. Codeforces 1109D Sasha and Interesting Fact from Graph Theory (看题解) 组合数学

    Sasha and Interesting Fact from Graph Theory n 个 点形成 m 个有标号森林的方案数为 F(n, m) = m * n ^ {n - 1 - m} 然后就 ...

随机推荐

  1. Django,Flask中的request

    request的结构获取 class Upload(Resource): def post(self): print(curPath) print(request.files['file'].__di ...

  2. k8s之 pod调度

    案例:确保Pod分配到具有SSD硬盘的节点上 第一步:给节点添加标签 格式:kubectl label nodes <node-name> <label-key>=<la ...

  3. pgsql中over函数的应用

    -- sum() over(partition by ... order by ...)SELECT len/sum(len)over(partition by road_id) param from ...

  4. Containerd 安装及使用(yum及源码)

    yum 安装containerd 一.下载源码库: wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker- ...

  5. C# 读取串口设备列表

    ManagementObjectSearcher 解析不到头文件,需要手动 Add Referance 需要添加引用:System.Management,然后引入命名空间:using System.M ...

  6. 容器逃逸 --with docker.sock

    容器逃逸 --with docker.sock 本人对于容器逃逸的基本理解就是用户从容器中逃出去到宿主机里去了. 本文意在记录一个使用 docker.sock 来进行容器逃逸的方法. 首先随便来个镜像 ...

  7. 利用shell脚本来监控linux系统的负载与CPU占用情况

    一.安装linux下面的一个邮件客户端msmtp软件(类似于一个foxmail的工具) 1.下载安装: http://downloads.sourceforge.net/msmtp/msmtp-1.4 ...

  8. 如何添加Eclipse项目到SVN资源库

    Eclipse项目添加到SVN版资源库有如下好处:一是轻松备份,每天做的修改内容一键提交:二方便合作,比较大的项目,多个人一起工作的时候,每人及时将完成的代码提交,别人可以下载浏览:三展示项目完成进度 ...

  9. 前台主页功能-前台轮播图功能完成-git介绍和安装-git使用流程-git常用命令-git忽略文件

    目录 前台主页功能-前台轮播图功能完成-git介绍和安装-git使用流程-git常用命令-git忽略文件 昨日内容回顾 今日内容概要 今日内容详细 0 导出项目依赖 0 学长问题解析 1 前台主页功能 ...

  10. Go组件库总结之无等待锁

    本篇文章我们用Go封装一个无等待锁库.文章参考自:https://github.com/brewlin/net-protocol 1.锁的封装 type Mutex struct { v int32 ...