zoukankan      html  css  js  c++  java
  • NOIP 2020 T1 排水系统(拓扑排序)

    NOIP 2020 T1 排水系统

    题解

    • 很显然是拓扑排序,按题意直接模拟复杂度仅仅是 O ( n ) O(n) O(n)的。
    • 但是涉及到分数的加法,通分会爆变量范围吗?
    • 一开始以为最大只是 5 11 ∗ 10 5^{11}*10 51110,连int都不会爆,保险起见还是开了long long。
    • 这样其实是错误的,不能只考虑一条链上,三条深度为 11 11 11的链,在最后的位置合并,分母最大可以到 ( 3 ∗ 4 ∗ 5 ) 11 = 6 0 11 ≈ 2 65 (3*4*5)^{11}=60^{11}≈2^{65} (345)11=6011265,long long都已经无法承受。
    • 如果开了long long,且分数相加时分母取LCM先除后乘,可以得到 90 90 90分;
    • 如果先乘后除,或者分数相加时分母直接相乘, 只可以得到 60 60 60分。
    • 想通过这道题,可以写一个两位数的高精度,或者用long double,注意运算时的精度。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 100010
    #define M 500010
    #define ld long double
    #define e 0.000000000001
    int last[N], nxt[M * 2], to[M * 2], len = 0;
    int d0[N], d[N];
    int q[N];
    struct {
    	ld x, y;
    }s[N];
    void add(int x, int y) {
    	to[++len] = y;
    	nxt[len] = last[x];
    	last[x] = len;
    }
    ld fl(ld x) {
    	ld y = floor(x);
    	if(y + 1.0 - e <= x) y++;
    	return y;
    }
    ld gcd(ld x, ld y) {
    	return (y >= -e && y <= e) ? x : gcd(y, x - fl(x / y) * y);
    }
    int main() {
    	int n, m, i, j, x, y;
    	scanf("%d%d", &n, &m);
    	for(i = 1; i <= n; i++) {
    		scanf("%d", &d0[i]);
    		for(j = 1; j <= d0[i]; j++) scanf("%d", &x), d[x]++, add(i, x);
    	}
    	int l = 0, r = 0;
    	for(i = 1; i <= n; i++) s[i].y = 1;
    	for(i = 1; i <= n; i++) if(!d[i]) q[++r] = i, s[i].x = 1;
    	int tt = 0;
    	while(l < r) {
    		x = q[++l];
    		for(int i = last[x]; i; i = nxt[i]) {
    			y = to[i];
    			ld X = s[x].x, Y = s[x].y * d0[x];
    			ld g = gcd(s[y].y, Y);
    			s[y].x = s[y].y / g * X + Y / g * s[y].x;
    			s[y].y = s[y].y / g * Y;
    			d[y]--;
    			if(!d[y]) q[++r] = y;
    		}
    	}
    	for(i = 1; i <= n; i++) if(!d0[i]) {
    		ld g = gcd(s[i].x, s[i].y);
    		printf("%.0Lf %.0Lf
    ", s[i].x / g, s[i].y / g);
    	}
    	return 0;
    }
    

    自我小结

    • 考虑问题时还不够全面,同时写代码没有注意细节差异,所谓“差不多”差距可能很大。
    • 需要日常训练积累经验,避免细节大丢分的情况。
  • 相关阅读:
    spring data jpa 动态查询(mysql)
    C#面向对象15 多态
    Visual Studio 2012网站如何只生成一个DLL文件
    C#面向对象14 List泛型集合/装箱和拆箱/字典集合(Dictionary)
    C#面向对象13 文件类操作 Path/File/FileStream
    C#面向对象12 集合
    C#面向对象11 里氏转换
    C#面向对象10 继承
    C#面向对象9 字符串
    C# 面向对象8 值类型和引用类型
  • 原文地址:https://www.cnblogs.com/LZA119/p/14279493.html
Copyright © 2011-2022 走看看