D154 拓扑排序 P7113 [NOIP2020] 排水系统

D154 拓扑排序 P7113 [NOIP2020] 排水系统_哔哩哔哩_bilibili

 

P7113 [NOIP2020] 排水系统 - 洛谷

有向无环图,m 个入口结点,n 个非入口结点,每个入口灌入单位 1 的水,求每个出口的出水量 $p/q$

$1\le n\le 10^5,1\le m\le 10,0\le d_i​\le 5$

思路

有向无环图,跑拓扑排序,累计结点的出水量

怎样累计从 u 点流到 v 点的水量?

用 u 点的水量 $\frac{u_1}{u_2}$ 乘以 u 点的出度分之一,累计到 v 点已有的水量 $\frac{v_1}{v_2}$

要先通分,算出分子、分母,再求两者的最大公约数,化简分数

分母的最大值怎样估算?

考虑三条出度分别为 5、4、3(因为它们互质)的“毛刷链”,累计水量的分母分别为 $5^{10},4^{10},3^{10}$,通分的乘积为 $6\times 10^{17}$

再考虑同样的三条“毛刷链”,通分的乘积为 $6\times 10^{17}$,这六条“毛刷链”通分的乘积约为 $3\times 10^{35}$

64 位的 $long\; long$ 型,约为 $1\times 10^{19}$;128 位的 $\_\_128int$ 型,约为 $3\times 10^{38}$,所以用 $\_\_128int$ 或高精度

 相关板子:

D01【模板】拓扑排序 - 董晓 - 博客园

 

// 拓扑排序 O(n)
#include<bits/stdc++.h>
#define i8 __int128
using namespace std;

int read(){
  int x=0; char c=getchar();
  while(c<'0'||c>'9') c=getchar();
  while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
  return x;
}
const int N=100005;
int h[N],idx,ne[N*5],to[N*5];
void add(int u,int v){
  to[++idx]=v;ne[idx]=h[u];h[u]=idx;
}
int n,m,cd[N],rd[N]; //出度,入度
i8 fz[N],fm[N]; //分子,分母

i8 gcd(i8 x,i8 y){ //求最大公约数
  i8 t;
  while(y){
    t=y;
    y=x%y;
    x=t;
  }
  return x;
}
void calc(i8 &v1,i8 &v2,i8 u1,i8 u2){ //求v1/v2+u1/u2
  v1=v1*u2+v2*u1;
  v2=v2*u2;
  i8 g=gcd(v1,v2);
  v1/=g;
  v2/=g;
}
void topo(){ //拓扑排序
  queue<int> q;
  for(int i=1;i<=m;++i){
    fz[i]=1;   //分子初值
    q.push(i); //m个入口入队
  }  
  while(!q.empty()){
    int u=q.front(); q.pop();
    for(int i=h[u];i;i=ne[i]){
      int v=to[i];
      calc(fz[v],fm[v],fz[u],fm[u]*cd[u]);
      if(--rd[v]==0) q.push(v);
    }
  } 
}
void write(i8 x){ //大数字输出
  if(x>9) write(x/10);
  putchar(x%10+'0');
}
int main(){
  n=read(),m=read();
  for(int i=1,d;i<=n;++i){
    d=read();
    fm[i]=1;  //分母初值
    cd[i]+=d; //出度
    for(int j=1,x;j<=d;++j){
      x=read();
      add(i,x);
      rd[x]++; //入度
    }
  }
  
  topo();
  for(int i=1;i<=n;++i)if(!cd[i]){ //枚举出口
    write(fz[i]); putchar(' ');
    write(fm[i]); putchar('\n');
  }
  return 0;
}

 

posted @ 2026-05-02 18:50  董晓  阅读(72)  评论(0)    收藏  举报