【UOJ #279】【UTR #2】题目交流通道
http://uoj.ac/problem/279
先判断答案为0的情况,\(d(i,i)\neq 0\),\(d(i,j)\neq d(j,i)\),\(d(i,j)>d(i,k)+d(k,j)\),\(d(i,j)>k\)。
对于\(d(i,j)>0\)的情况,如果存在\(k\neq i,j\)且满足\(d(i,j)=d(i,k)+d(k,j)\),那么i和j的边就可以取d(i,j)~k的所有权值,答案乘上\(k-d(i,j)+1\)即可。
如果存在\(d(i,j)=0\)的情况,用并查集把最短距离为0的点缩起来,形成许多连通块。两个连通块之前会有很多边,且这些边的d值相同。把连通块看成一个点,那么就成了上一行的问题中有d值相同重边的情况;设ij之间的重边数为a,这个情况中如果存在上一行所述的k,答案乘上\((k-d(i,j)+1)^a\);如果不存在上一行所述的k,答案乘上\((k-d(i,j)+1)^a-(k-d(i,j))^a\)。
对于每个连通块内的方案数,假设连通块大小为n,设边权为0的边连通整个连通块的方案数为\(f(n)\),不管连不连通所有边权任意的方案数为\(g(n)\),因为这个连通块是个完全图,所以\(g(n)=(k+1)^{\frac{n(n-1)}2}\),同时:$$f(n)=g(n)-\sum_{i=1}^{n-1}f(i)g(n-i)
\begin{pmatrix}n-1\i-1\ \end{pmatrix} k^{i(n-i)}$$
先定住一个连通块内的点x,转移时枚举包括x的连通块的大小\(f(i)\)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 403;
const int p = 998244353;
int fa[N], d[N][N], n, k, F[N], G[N], jc[N], jcn[N], cnt[N][N], sum[N];
inline int ipow(int a, int b) {
int r = 1, w = a;
while (b) {
if (b & 1) r = 1ll * r * w % p;
b >>= 1;
w = 1ll * w * w % p;
}
return r;
}
inline int C(int a, int b) {return 1ll * jc[a] * jcn[b] % p * jcn[a - b] % p;}
inline void sub(int &a, int b) {a -= b; if (a < 0) a += p;}
int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);}
inline void merge(int a, int b) {
if ((a = find(a)) != (b = find(b)))
fa[a] = b;
}
int ans = 1;
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) {
scanf("%d", &d[i][j]);
if (d[i][j] > k) {puts("0"); return 0;}
}
for (int i = 1; i <= n; ++i) {
if (d[i][i] != 0) {puts("0"); return 0;}
for (int j = i + 1; j <= n; ++j)
if (d[i][j] != d[j][i])
{puts("0"); return 0;}
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
for (int kk = 1; kk <= n; ++kk)
if (d[i][j] > d[i][kk] + d[kk][j])
{puts("0"); return 0;}
jc[0] = jcn[0] = 1;
for (int i = 1; i <= n; ++i) {
jc[i] = 1ll * jc[i - 1] * i % p;
jcn[i] = ipow(jc[i], p - 2);
}
for (int i = 1; i <= n; ++i) {
F[i] = G[i] = ipow(k + 1, i * (i - 1) / 2);
for (int j = 1; j < i; ++j)
sub(F[i], 1ll * F[j] * G[i - j] % p * C(i - 1, j - 1) % p * ipow(k, j * (i - j)) % p);
}
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j)
if (d[i][j] == 0)
merge(i, j);
int u, v;
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j)
if ((u = find(i)) != (v = find(j)))
++cnt[u][v], ++cnt[v][u];
int a;
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j)
if (a = cnt[i][j]) {
bool flag = false;
for (int kk = 1; kk <= n; ++kk)
if (cnt[i][kk] && cnt[kk][j] && d[i][j] == d[i][kk] + d[kk][j]) {
flag = true;
break;
}
if (flag) ans = 1ll * ans * ipow(k - d[i][j] + 1, a) % p;
else ans = 1ll * ans * ((ipow(k - d[i][j] + 1, a) - ipow(k - d[i][j], a) + p) % p) % p;
}
for (int i = 1; i <= n; ++i) ++sum[find(i)];
for (int i = 1; i <= n; ++i)
if (sum[i]) ans = 1ll * ans * F[sum[i]] % p;
printf("%d\n", ans);
return 0;
}
【UOJ #279】【UTR #2】题目交流通道的更多相关文章
- 【UTR #2】[UOJ#278]题目排列顺序 [UOJ#279]题目交流通道 [UOJ#280]题目难度提升
[UOJ#278][UTR #2]题目排列顺序 试题描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 UOI. 这场比赛有 n 道题,吉米多出题斯基需要决定这 ...
- uoj#279. 【UTR #2】题目交流通道(容斥+数数)
传送门 先考虑无解的情况,为以下几种:\(dis_{i,j}+dis_{j,k}<dis_{i,k}\),\(dis_{i,i}\neq 0\),\(dis_{i,j}\neq dis_{j,i ...
- UOJ279 【UTR #2】题目交流通道
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump ...
- 【UTR #2】题目交流通道
题目描述 定好了难度,雄心勃勃的吉米多出题斯基开始寻找智慧的神犇星球的居民出题. 然而吉米多出题斯基没有料到,神犇星球的居民告诉吉米多出题斯基:"今年神犇星球经济不景气,大家都想宅在家里,哪 ...
- uoj279题目交流通道(dp)
题目大意: 神犇星球有 \(n\) 座小城.对于任意两座小城 \(v,u\)\((v≠u)\),吉米多出题斯基想在 \(v,u\) 之间建立一个传送时间为 \(w(v,u)\)的无向传送通道,其中 \ ...
- uoj279 题目交流通道
题目:告诉你每两个点之间的最短路距离.构造每条边边权<=m的无向完全图.求有多少种不同边权的图满足最短路限制?n<=400. 标程: #include<cstdio> #inc ...
- 【uoj#280】[UTR #2]题目难度提升 对顶堆+STL-set
题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其 ...
- UOJ Test Round #2
昨天晚上打的这个比赛,简直一颗赛艇啊-- 感觉发挥的并不好.比赛的时候比较紧张,最后一题还脑残写了个离散化结果爆零了,哎我怎么这么逗逼-- 讲讲比赛经过吧. 比赛之前逗逼地以为是8:00开始,然后淡定 ...
- 「总结」$dp1$
大概就是做点题. 先列一下要做的题目列表,从\(UOJ\)上找的. 129寿司晚宴 348州区划分 370滑稽树上滑稽果 457数树 22外星人 37主旋律 300吉夫特 196线段树 311积劳成疾 ...
随机推荐
- Linux中关机,重启,注销命令
关机: shutdown -h now #立刻关机重启,工作中常用 shutdown -h +1 #1分钟后关机 init 0 halt #立即停 ...
- sumblime快捷键
原文地址:https://blog.csdn.net/shutfuckingup/article/details/23846603 Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的 ...
- 头像截取 图片上传 js插件
先看一下整体效果 页面html <div class="row"> <div class="tabs-container"> <u ...
- js_!和!!的使用
js中有些特殊的数据(“” 0 null undefined NaN),请求后台返回的数据中往往都有一些这样的数据,需要对这些数据进行过滤. 过滤代码 var a = 0;//0 "&quo ...
- beego 相关
bee api bapi bee run -downdoc=true -docgen=true
- SSH 登录失败:Host key verification failed 的处理方法
原因就是你之前已经登录过这个服务器了然后改系统啥的了.导致目标主机 key 值不正确.直接把本机的key文件删除即可 sudo rm /home/yourname/.ssh/known_hosts
- mysql之数据库操作进阶(三)
环境信息 数据库:mysql-5.7.20 操作系统:Ubuntu-16.04.3 查询 条件查询 # 使用where关键字 select * from 表名 where 条件 # 比较运算符 > ...
- python基础===输入必须为数字的检验的另一种方法
print("[+]welcome to python3") while True: num = input("please input a num:") if ...
- Oracle例外定义
例外名 ORA-XXXXX SQLCODE ACCESS_INTO_NULL ORA-06530 -6530 CASE_NOT_FOUND ORA-06592 -6592 COLLECTION_IS_ ...
- vue-router 基础
安装 NPM npm install vue-router 如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能: import Vue from 'vue' import ...