P7113 [NOIP2020] 排水系统 题解
题意
有一个图(DAG),n个节点,m个入度为0的点,每个入度为0的节点有一吨水,每个结点的水会平均地沿着边分给相邻的点,求每个出度为0的节点的水有多少。
前置芝士
- 拓扑排序
- 最大公因数
- 快写 / 高精度
思路
注意到这是一个DAG(有向无环图),我们可以使用拓扑排序,并在其过程中统计每个节点会收集到的水的重量。最终输出出度为0的节点的水的重量。
tips:
- 可以分别用两个数组存储每个节点水的重量分子和分母
计算分数加和的代码
void add(int v,int u){//将v的水的重量的出度分之一加入u的水的重量
fz[v]=fz[v]*(fm[u]*out[u])/gcd(fm[v],fm[u]*out[u])+fz[u]*(fm[v])/gcd(fm[v],fm[u]*out[u]);
fm[v]=fm[v]*fm[u]*out[u]/gcd(fm[v],fm[u]*out[u]);
}
void print(__int128 x){//__int128无法使用cout等,给__int128写快写
if (!x) return ;
if (x < 0) putchar('-'),x = -x;
print(x / 10);
putchar(x % 10 + '0');
}
- 观察数据范围,发现int和long long都存不下,但是可以使用__int128来存储分子和分母,__int128并不能用printf或cout输出,所以需要自己写一个快写。当然,你也可以选择写高精度。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
const int MAXM=13;
int n,m;
int inb[MAXN];
__int128 out[MAXN];//记得开__int128或者写高精度哦
vector<int>vec[MAXN];
__int128 fm[MAXN],fz[MAXN];
queue<int> q;
__int128 gcd(__int128 a,__int128 b){//计算gcd(最大公约数)
while(b){
__int128 t=a%b;
a=b,b=t;
}
return a;
}
void add(int v,int u){//将v的水的重量的出度分之一加入u的水的重量
fz[v]=fz[v]*(fm[u]*out[u])/gcd(fm[v],fm[u]*out[u])+fz[u]*(fm[v])/gcd(fm[v],fm[u]*out[u]);
fm[v]=fm[v]*fm[u]*out[u]/gcd(fm[v],fm[u]*out[u]);
}
void print(__int128 x){//__int128无法使用cout等,给__int128写快写
if(!x) return ;
if(x < 0) putchar('-'),x=-x;
print(x/10);
putchar(x%10+'0');
}
void sor(){//拓扑排序
for(int i=1;i<=n;i++){
if(inb[i]==0){
fz[i]=1;
q.push(i);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<vec[u].size();i++){
int v=vec[u][i];
add(v,u);//将v的水的重量的出度分之一加入u的水的重量
inb[v]--;
if(inb[v]==0){
q.push(v);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int xx;
cin>>xx;
out[i]=xx;
fm[i]=1;
for(int j=1;j<=out[i];j++){
int v;
cin>>v;
vec[i].push_back(v);
inb[v]++;
}
}
sor();
for(int i=1;i<=n;i++){
if(out[i]==0){
__int128 G=gcd(fz[i],fm[i]);
fz[i]/=G;
fm[i]/=G;
print(fz[i]);
cout<<" ";
print(fm[i]);
cout<<endl;
}
}
}
结语
第一次写题解,有问题欢迎指出喵:D
作者:Le-Louvre
出处:https://www.cnblogs.com/Le-Louvre/p/18366450
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现