【UTR #2】题目交流通道
题目描述
定好了难度,雄心勃勃的吉米多出题斯基开始寻找智慧的神犇星球的居民出题。
然而吉米多出题斯基没有料到,神犇星球的居民告诉吉米多出题斯基:“今年神犇星球经济不景气,大家都想宅在家里,哪有心思出来出题呢?”
为了挽救这一局面,吉米多出题斯基决定为神犇星球建一些高速传送通道促进该星球各地区之间交流题目。
神犇星球有 $n$ 座小城。对于任意两座小城 $v, u$($v \neq u$),吉米多出题斯基想在 $v, u$ 之间建立一个传送时间为 $w(v, u)$ 的无向传送通道,其中 $w(v, u)$ 为不超过 $k$ 的非负整数。建成后,神犇星球的居民可从一座小城出发经过一个或若干个传送通道到达另一座小城交流题目,花费的时间为所有经过的传送通道的传送时间之和。
吉米多出题斯基还没有决定每一个传送通道的传送时间取值,只是对于任意两座小城 $v, u$,决定了从 $v$ 出发到达 $u$ 的最短时间要恰好等于 $d(v, u)$。但吉米多出题斯基日理万机,于是他找到了你 —— 风璃殇做不出题耶维奇,请你帮助吉米多出题斯基数一数有多少种不同的满足条件的传送通道建设方案吧!
由于方案数可能很大,你只用输出方案数对 $998244353$($7 \times 17 \times 2^{23}+1$,一个质数)取模后的结果。
输入
第一行两个整数 $n, k$。保证 $n \ge 1, k \ge 0$。
接下来 $n$ 行,每行有 $n$ 个非负整数,第 $i$ 行的 第 $j$ 个数表示 $d(i,j)$ 的值。
输出
输出一行,一个整数,表示方案数对 $998244353$ 取模的结果。如果无解,则方案数为 $0$。
限制与约定
对于所有数据,有 $1\leq n\leq 400, 0\leq k\leq 10^9, 0\leq d(u,v)\leq 10^{9}$
子任务 | 分值 | $n$ | $k$ | 其他限制 |
---|---|---|---|---|
1 | 30 | $1 \leq n \leq 4$ | $0\leq k\leq 5$ | |
2 | 30 | $1 \leq n \leq 400$ | $0\leq k\leq 10^9$ | 对于所有 $u\neq v$,有 $d(u,v)\geq 1$ |
3 | 40 | $1 \leq n \leq 400$ | $0 \leq k \leq 10^9$ |
分析1
对于第一个子任务,当最大\(n=4\)的时候有\(6\)条边,暴力设定每条边的边权,然后Floyd跑一遍验证一下即可
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#define LL long long
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc();int b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
int wt,ss[19];
inline void print(int x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {
for (wt=0;x;ss[++wt]=x%10,x/=10);
for (;wt;putchar(ss[wt]+48),wt--);}
}
int n,m,ans,a[410][410],b[410][410],c[10];
bool check()
{
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i!=j && i!=k && j!=k)
if (b[i][k]+b[k][j]<b[i][j]) b[i][j]=b[i][k]+b[k][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (b[i][j]!=a[i][j]) return false;
return true;
}
void dfs(int x)
{
if (x==n*(n-1)/2+1)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i==j) b[i][j]=0;else b[i][j]=-1;
int s=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (b[i][j]==-1) b[i][j]=c[++s],b[j][i]=c[s];
if (check()) ans++;
return ;
}
for (int i=0;i<=m;i++)
c[x]=i,dfs(x+1);
}
int main()
{
read(n);read(m);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
read(a[i][j]);
ans=0;
dfs(1);
print(ans);puts("");
return 0;
}
分析2
对于第二个子任务,数据的特点是\(d(x,y)\geq 1(x\neq y)\)
那么对于一条边\((x,y)\),他的\(d(x,y)\)有两种方式得到,一种是其本身就是最短边,或者是通过两条最短边合成的,即\(d(x,y)=d(x,k)+d(k,y)(x\neq z且y\neq z)\)
那么,对于每一个\((x,y)\),探索是否存在这样一个\(z\),若存在,这条边的边权范围是\([d(x,y),k]\),否则就是能是\(d(x,y)\)了
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#define LL long long
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc();int b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
int wt,ss[19];
inline void print(LL x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {for (wt=0;x;ss[++wt]=x%10,x/=10);for (;wt;putchar(ss[wt]+48),wt--);}
}
int n,m,a[410][410];
LL f[410][410];
const LL mo=998244353;
bool check(int x,int y)
{
for (int i=1;i<=n;i++)
if (i!=x && i!=y)
if (a[x][i]+a[i][y]==a[x][y]) return true;
return false;
}
int main()
{
read(n);read(m);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
read(a[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
if (check(i,j)) f[i][j]=(LL)(m-a[i][j]+1);
else f[i][j]=1LL;
}
LL ans=1;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
ans=ans*f[i][j]%mo;
print(ans),puts("");
return 0;
}
分析3
结合分析1和分析2可以得到60分...还不错了啊......
满分算法的分析...我就把劼的题解搬过来吧......
考虑边可以等于 $0$ 的情况,这时 $d_{u,v}=0$ 的边肯定在图中连成了若干个团。我们把每一个团给缩起来。
两个团之间的点对距离一定是相等的,考虑团与团之间的边,此时相当于有重边的 $d_{u,v}>0$ 的情况。假设这是一条 $a$ 重边,如果存在 $k$ 有 $d_{u,v}=d_{u,k}+d_{k,v}$,那么所有边只要大于等于 $d_{u,v}$ 就可以了,即有 $(K-d_{u,v}+1)^a$ 种方案。如果不存在,那么至少要有一条边等于 $d_{u,v}$,其他边都要大于它,即有 $(K-d_{u,v}+1)^a-(K-d_{u,v})^a$ 种方案。
考虑团内部的边,每个团肯定由 $0$ 的边连成了一个联通块,这是一个经典的容斥,令 $f_i$ 为 $n$ 个点的距离为 $0$ 的团的方案数,$g_i$ 为 $n$ 个点的图的方案数。则有 $g_n=(K+1)^{\binom{n}{2}}$,$f_n=g_n-\sum_{i=1}^{n-1} f_i \times g_{n-i} \times \binom{n-1}{i-1} \times K^{i(n-i)}$。
把所有部分的答案乘起来就好了。时间复杂度 $O(n^3)$,期望得分 $100$ 分。
当然最重要的是要判对无解的情况,大致有四种,分别是 $d_{i,j} >K$,$d_{i,i} \neq 0$,$d_{i,j} \neq d_{j,i}$,$d_{i,j} > d_{i,k}+d_{k,j}$,大力 check 一下就可以了。
【UTR #2】题目交流通道的更多相关文章
- 【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 ...
- 【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 ...
- 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开始,然后淡定 ...
- Noip模拟62 2021.9.26
T1 Set 真就随机化拿了$90$?? 不过还是有依据的,毕竟这道题出解的几率很大,随出答案的概率也极大 所以不妨打一个随机化 1 #include<bits/stdc++.h> 2 # ...
随机推荐
- Java代码中的(解压7z加密版)
maven:需要加上这个下载这两个包 <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <art ...
- Python9-进程理论-day35
#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:Tim'''进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源 ...
- CodeForces 570D DFS序 树状数组 Tree Requests
参考九野巨巨的博客. 查询一个子树内的信息,可以通过DFS序转成线形的,从而用数据结构来维护. #include <iostream> #include <cstdio> #i ...
- vi 编辑器命令
插入命令 a append after the cursor A append after the current line i insert before the cursor I insert b ...
- python - work3
# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: work_20181107.py@ide: PyCharm Communit ...
- C++ 将string转换成char*字符串
我们经常会使用C和C++的混合编程,在某些情况下,需要将C++的string,转换成char* 的字符串.下面说两种可行的方法,作为总结. 1. data(); 如: string str=" ...
- DB2 和 有道词典冲突: A communication error has been detected. Communication protocol being used: Reply.fill().
我在本机安装了DB2 9.5. 使用java jdbc连接,一直没有问题. QC for db2 连接 也一直没有问题. 突然有一天 Java程序连接 报错: A communication erro ...
- 使用PHPExcel单元格样式添加不上的原因
按照文档上的样式设置方法设置样式,一直不成功.后来发现是得要在创建了sheet,并选择某一个sheet作为活动sheet后再设置才可以.这里记录一下.
- git命令综合
Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势.Git常用操作命令:1) 远程仓库相关命令检出仓库:$ git clone git: ...
- HDU——1061Rightmost Digit(高次方,找规律)
Rightmost Digit Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...