带 gcd 的纯模拟。( gcd 就是求最大公约数)
gcd 用来处理分数相加时的分母通分和分数的约分,
通过 gcd 珂以求出 lcm (最小公倍数):
\(\operatorname{lcm}(x,y)=\frac{x \times y}{\gcd(x,y)}\)
开个结构体存分数,然后就珂以愉快地拓扑排序了。
最后几个点 WA 是因为 long long 不够用,
开个 __int128 就能过了。
考场上就乖乖写高精吧(逃
代码:
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#define Rei register int
#define ll __int128 //注意是两个下划线!
using namespace std;
template<typename T>
inline void read(T &x) {
x=0;
char f=0,c;
while(c=getchar(),!isdigit(c)) if(c=='-') f=1;
if(f) while(isdigit(c)) x=x*10-c+48,c=getchar();
else while(isdigit(c)) x=x*10+c-48,c=getchar();
}
void write(__int128 x) { //__int128需要手写输入输出
if(x/10) write(x/10);
putchar(x%10+'0');
}
inline ll gcd(ll x,ll y) { //辗转相除法求gcd
ll t;
while(y) t=x%y,x=y,y=t;
return x;
}
const int N=1e5+2;
int n,m,cnt,rbq,son;
int h[N],rd[N],d[N];
struct node {
int next,to;
node(int next=0,int to=0) {
this->next=next,this->to=to;
}
} b[N*5];
struct fenshu {
ll fenzi,fenmu;
fenshu(ll fenzi=0,ll fenmu=1) { //注意分母不能为0
this->fenzi=fenzi,this->fenmu=fenmu;
}
void huajian() { //分数的化简
ll g=gcd(fenzi,fenmu);
fenzi/=g,fenmu/=g;
}
} O2[N];
fenshu jia(fenshu x,fenshu y) { //这里自己推一下就懂了
ll g=gcd(x.fenmu,y.fenmu);
ll k1=y.fenmu/g,k2=x.fenmu/g;
return fenshu(x.fenzi*k1+y.fenzi*k2,x.fenmu*k1);
}
inline void link(int u,int v) {
b[++cnt]=node(h[u],v),h[u]=cnt,++rd[v];
}
queue<int> q;
vector<int> ans;
void tuopu() { //拓扑排序
for(Rei i=1; i<=n; ++i) {
if(!rd[i]) {
q.push(i);
O2[i]=fenshu(1,1);
}
}
while(!q.empty()) {
rbq=q.front(),q.pop();
if(!d[rbq]) {
ans.push_back(rbq);
continue;
}
O2[rbq].fenmu*=d[rbq]; //水分流
O2[rbq].huajian();
for(Rei i=h[rbq]; i; i=b[i].next) {
--rd[son=b[i].to];
O2[son]=jia(O2[son],O2[rbq]);
O2[son].huajian();
if(!rd[son]) {
q.push(son);
}
}
}
}
int main() {
read(n),read(m);
for(Rei i=1; i<=n; ++i) {
read(d[i]);
for(Rei j=1; j<=d[i]; ++j) {
read(rbq),link(i,rbq);
}
}
tuopu();
sort(ans.begin(),ans.end());
for(int i=0; i<ans.size(); ++i) {
write(O2[ans[i]].fenzi),putchar(' ');
write(O2[ans[i]].fenmu),putchar('\n');
}
return 0;
}
第一次写题解,请多包涵。