#include<bits/stdc++.h>
// #define int __int128
using namespace std;
const int N=1e7+10;
int n,m;
int in[N],out[N],cd[N];
//入度数 第i个出口的编号 出度数
int ans[N];
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void prints(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9){
prints(x/10);
}
putchar(x%10+'0');
}
int gcd(int a,int b){
if(a<b)swap(a,b);
if(b){
return gcd(b,a%b);
}
return a;
}
struct node{
int nxt,to;
}e[N];
int head[N],tot;
void adg(int u,int v){
e[++tot]=(node){head[u],v};
head[u]=tot;
}
struct frac{
int up,down;
void clr(){
up=0,down=1;
}
}fra[N];
frac addfrac(frac x,frac y){
int ai=x.down,bi=x.up;
int ci=y.down,di=y.up;
int nup=bi*ci+ai*di;
int ndown=ai*ci;
int tmp=gcd(nup,ndown);
nup/=tmp,ndown/=tmp;
return (frac){nup,ndown};
}
void dfs(int u){
if(cd[u]==0){
return;
}
fra[u].down*=cd[u];
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
fra[v]=addfrac(fra[u],fra[v]);
dfs(v);
}
fra[u].clr();
}
queue<int> st;
void toposort(){
for(int i=1;i<=n;i++){
if(in[i]==0){
st.push(i);
fra[i]=(frac){1,1};
}
}
while(st.size()){
int u=st.front();
st.pop();
int tmp=cd[u];
fra[u].down*=tmp;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
fra[v]=addfrac(fra[u],fra[v]);
if(--in[v]==0 && cd[v]!=0)st.push(v);
}
fra[u].clr();
}
}
signed main(){
// freopen("water3.in","r",stdin);
// freopen("water3.out","w",stdout);
n=read(),m=read();
int cnt=0;
for(int i=1;i<=n;i++){
fra[i]=(frac){0,1};
int x;
x=read();
cd[i]=x;
if(x==0) out[++cnt]=i;
else while(x--){
int to=read();
in[to]++;
adg(i,to);
}
}
// for(int i=1;i<=n;i++){
// if(in[i]==0){
// fra[i]=(frac){1,1};
// dfs(i);
// }
// }
toposort();
for(int i=1;i<=n;i++){
if(cd[i]==0){
prints(fra[i].up);
printf(" ");
prints(fra[i].down);
printf("\n");
}
}
return 0;
}
注释部分dfs过了这题,也就是问题大概就在拓扑这,求助dalao