uoj279题目交流通道(dp)
题目大意:
神犇星球有 \(n\) 座小城。对于任意两座小城 \(v,u\)\((v≠u)\),吉米多出题斯基想在 \(v,u\) 之间建立一个传送时间为 \(w(v,u)\)的无向传送通道,其中 \(w(v,u)\) 为不超过 \(k\) 的非负整数。建成后,神犇星球的居民可从一座小城出发经过一个或若干个传送通道到达另一座小城交流题目,花费的时间为所有经过的传送通道的传送时间之和。
吉米多出题斯基还没有决定每一个传送通道的传送时间取值,只是对于任意两座小城 \(v,u\),决定了从 \(v\)出发到达 \(u\) 的最短时间要恰好等于 \(d(v,u)\)。但吉米多出题斯基日理万机,于是他找到了你 —— 风璃殇做不出题耶维奇,请你帮助吉米多出题斯基数一数有多少种不同的满足条件的传送通道建设方案吧!
由于方案数可能很大,你只用输出方案数对 \(998244353\) 取模后的结果。
QwQ看到这个题 其实没什么思路
既然没什么思路,我们不妨先特判下不合法的情况
1.存在\(dis[i][k]+dis[k][j]<dis[i][j]\)
2.\(dis[i][j]!=dis[j][i]\)
3.\(dis[i][i]!=0\)
QwQ
看了题解,才知道是一个dp
首先,我们考虑不存在0边的情况,那么对于一条边存在\(dis[i][k]+dis[k][j]==dis[i][j]\),那么\(dis[i][j]\)这个边就可以取\([dis[i][j],k]\)这个范围内的值,那么它的贡献就是\(k-dis+1\)对吧
QwQ然后我们考虑
如果有0边怎么办QwQ
我们可以把所有的0边缩成一个点,先算完每个块每部的贡献,然后再算块外,最后合起来。
QwQ这是一个很值得纪念的一个小套路,我们令\(g[i]\)表示i个点相连的方案数,QwQ因为i个点一共有\(\frac{i(i-1)}{2}\),每个点有\(k+1\)种取值QwQ,所以\(g[i]\)显然等于\((k+1)^{\frac{i(i-1)}{2}}\), QwQ,然后我们令\(f[i]\)表示i个点互相相连,且互相的权值为0的合法方案数
我在计算\(f[i]\)的时候,用的是总方案-不合法的方案$$f[i]=g[i]-\sum_{j=1}^{i-1} C_{i-1}^{j-1} \times f[j] \times g[i-j] \times k^{j(i-j)}$$
QwQ这里的思路是 枚举有几个点相连成0团,然后钦定1个点为合法点,然后乘一乘组合数(一定要乘!!!), 乘上\(f[j]\)(因为0团内的点相连的方案必须是合法的。)再乘上\(g[i-j]\) 另外的点内部的连接是无所谓的。最后乘上\(k^{j(i-j)}\)因为两个团之间的连边不能是0,其余都可以
QwQ那么处理完这个数组呢 0团的内部的方案数也就能迎刃而解了
那么我们应该怎么把它合并起来呢?
对于两个团(点)\(i,j\)
如果存在\(a[i][k]+a[k][j]==a[i][j]\),那么\(ans=ans*qsm(k-a[i][j]+1,size[i]*size[j])\)
如果不存在...是不是没有贡献呢?
并不是这样的
如果不存在的话。我只需要枚举两个团之间至少有一条边是\(a[i][j]\)就行,这里运用了一个小tips
\(ans*(qsm(k-a[i][j]+1,size[i]*size[j])-qsm(k-a[i][j],size[i]*size[j])\)就是所有的情况减去,所有的边都是大于\(a[i][j]\)情况
总之这个题的细节还是很多很多的
直接上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define ll long long
using namespace std;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const ll mod = 998244353;
const int maxn = 510;
int fa[maxn];
ll f[maxn],g[maxn];
int n;
ll k;
ll ans=1;
ll a[maxn][maxn];
ll c[maxn][maxn];
int size[maxn];
int find(int x)
{
if (fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
ll qsm(ll i,ll j)
{
ll ans=1;
while (j)
{
if (j&1) ans=ans*i%mod;
i=i*i%mod;
j>>=1;
}
return ans;
}
void init(int n)
{
for (int i=0;i<=n;i++)
c[i][i]=1,c[i][0]=1;
for (int i=1;i<=n;i++)
for (int j=1;j<i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
int main()
{
scanf("%d%lld",&n,&k);
init(n);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=read();
bool flag = true;
for (register int i=1;i<=n;++i)
for (register int j=1;j<=n;++j)
{
if (a[i][i]!=0) flag=false;
if (a[i][j]!=a[j][i]) flag=false;
if (a[i][j]>k) flag=false;
}
for (register int k=1;k<=n;++k)
for (register int i=1;i<=n;++i)
for (register int j=1;j<=n;++j)
if (a[i][j]>a[i][k]+a[k][j]) flag=false;
if (!flag) {
cout<<0;
return 0;
}
f[0]=g[0]=1;
for (register int i=1;i<=n;i++){
g[i]=qsm(k+1,i*(i-1)/2);
f[i]=g[i];
for (register int j=1;j<=i-1;j++)
{
f[i]=(f[i]-c[i-1][j-1]*f[j]%mod*g[i-j]%mod*qsm(k,j*(i-j))%mod+mod)%mod;
}
}
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (i==j) continue;
if (!a[i][j]) fa[find(i)]=fa[find(j)];
}
}
for (int i=1;i<=n;i++) size[find(i)]++;
for (int i=1;i<=n;i++) if (fa[i]==i) for (int j=i+1;j<=n;j++) if (fa[j]==j)
{
bool ok=0;
for (int p=1;p<=n;p++)
{
if (fa[p]!=p) continue;
if (p==i || p==j) continue;
if (a[i][p]+a[p][j]==a[i][j]) {
ok=1;break;
}
}
if (ok) ans=ans*qsm(k-a[i][j]+1,size[i]*size[j])%mod;
else ans=ans*(qsm(k-a[i][j]+1,size[i]*size[j])-qsm(k-a[i][j],size[i]*size[j])+mod)%mod;
}
for (int i=1;i<=n;i++) if (fa[i]==i) ans=ans*f[size[i]]%mod;
cout<<ans;
return 0;
}
uoj279题目交流通道(dp)的更多相关文章
- uoj279 题目交流通道
题目:告诉你每两个点之间的最短路距离.构造每条边边权<=m的无向完全图.求有多少种不同边权的图满足最短路限制?n<=400. 标程: #include<cstdio> #inc ...
- 【UTR #2】[UOJ#278]题目排列顺序 [UOJ#279]题目交流通道 [UOJ#280]题目难度提升
[UOJ#278][UTR #2]题目排列顺序 试题描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 UOI. 这场比赛有 n 道题,吉米多出题斯基需要决定这 ...
- UOJ279 【UTR #2】题目交流通道
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump ...
- 【UTR #2】题目交流通道
题目描述 定好了难度,雄心勃勃的吉米多出题斯基开始寻找智慧的神犇星球的居民出题. 然而吉米多出题斯基没有料到,神犇星球的居民告诉吉米多出题斯基:"今年神犇星球经济不景气,大家都想宅在家里,哪 ...
- 【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 ...
- 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 ...
- AC题目简解-dp
dp类:A - Bridging signals ZOJ 3627 POJ1631 HDU1950给出一个从1-n的数字排列,求最长上升子序列长度.直接说解法吧.新开一个数组d,d[i]表示的是能构成 ...
- P1140 相似基因 这个和之前有一个题目特别像 dp
题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了444种核苷酸,简记作A,C,G,TA,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类 ...
- TOJ4101.Guess Game(TOJ means Tianjin University Online Judge)(dp的思想,但这道题目是假dp)
题意:你要从[1,n]这个n个数中猜出来规定的某个数,现在这个数未知,问你在最糟糕的情况下(但是你采用了最优的策略),你要猜多少次才能猜出这个数.现在有两种条件: 第一种:当你猜的数比指定的那个数小的 ...
随机推荐
- Hadoop day1
Hadoop就是存储海量数据和分析海量数据的工具 1.概念 Hadoop是由java语言编写的,在分布式服务器集群上存储海量数据并运行分布式分析应用的开源框架,其核心部件是HDFS与MapReduce ...
- Nginx的高级使用
1.概述 之前介绍过Nginx的简单使用,今天来聊聊Nginx的一些高级使用. 2.使用Nginx解决跨域问题 当公司存在多个域名时,两个不同的域名相互访问就会存在跨域问题. 或者在进行前端开发时,通 ...
- 源码解析Spring AOP的加载与生效
本次博主主要进行Spring AOP这里的解析,因为在工作中使用后,却不知道背后的实现原理并在使用的过程中发现了一些认知缺陷,所以决定写这么一篇文章以供大家参考参考,进入正题. 本次博主使用了@Asp ...
- Selenium系列(八) - 截取完整页面和截取指定元素并保存为图片
如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...
- AOP快速入门
一.概念 AOP面向切面编程,是函数式编程的延申,是对OOP的补充: 代理模式:拦截增强作用,增强功能: 1.java继承,纵向共性抽取, 2.横向切面AOP织入增强代码方式 二.原理是通过代理机制, ...
- C# 反射 + Quartz,实现流程处理
场景: 前不久,公司里项目经理要求我实现流程处理,比如,用户可以定义一个定时任务,每周一查看报表.定时任务很简单,用Quartz可以实现,但是用户自己选择报表就比较麻烦,因为系统的不同模块的生成报表的 ...
- 安装docker遇到:package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
执行 yum install docker-ce docker-ce-cli containerd.io 提示: 错误: 问题: package docker-ce-3:19.03.8-3.el7.x ...
- 知乎vscode插件修改和重新编译
需求来源 vscode插件修改代码要怎样重新编译并安装到vscode中? 起源于我使用一个vscode插件,它可以在vscode中发布文章到知乎上,然后我修改了插件的部分源代码,希望在vscode中安 ...
- PHP中的垃圾回收相关函数
之前我们已经学习过 PHP 中的引用计数以及垃圾回收机制的概念.这些内容非常偏理论,也是非常常见的面试内容.而今天介绍的则是具体的关于垃圾回收的一些功能函数.关于之前的两篇介绍文章,大家可以到文章底部 ...
- PHP匿名类的用法
在PHP7之后,PHP中加入了匿名类的特性.匿名类和匿名方法让PHP成为了更现代化的语言,也让我们的代码开发工作越来越方便.我们先来看看匿名类的简单使用. // 直接定义 $objA = new cl ...