Code:
#include<bits/stdc++.h>
using namespace std;
struct num
{
long long p,q;
num(long long _p=0,long long _q=1):p(_p),q(_q) //我怀疑是这里用了下划线
{
}
num change()
{
num ans(*this);
for(long long i=2;i<=ans.p&&i<=ans.q;i++)
{
while(ans.p%i==0&&ans.q%i==0)
{
ans.p/=i;
ans.q/=i;
}
}
return ans;
}
};
num operator+(const num &a,const num &b)
{
return num(a.p*b.q+b.p*a.q,a.q*b.q).change();
}
int n,m;
list<int> maps[100001];
num water[100001];
bool flag[100001];
inline void bfs()
{
queue<int> q;
for(int i=1;i<=m;i++)
{
water[i].p=1;
flag[i]=1;
q.push(i);
}
while(!q.empty())
{
int at=q.front();
q.pop();
flag[at]=0;
water[at]=water[at].change();
num tmp(water[at].p,water[at].q*maps[at].size());
for(list<int>::iterator i=maps[at].begin();i!=maps[at].end();i++)
{
int new_at=*i;
water[new_at]=water[new_at]+tmp;
if(!flag[new_at])
{
flag[new_at]=1;
q.push(new_at);
}
}
if(maps[at].size()!=0) water[at]=num(0,1);
}
}
inline num solve()
{
bfs();
for(int i=1;i<=n;i++)
{
if(maps[i].size()==0) printf("%d %d\n",water[i].p,water[i].q);
}
}
int main()
{
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
int d;
scanf("%d",&d);
for(int j=0;j<d;j++)
{
int to;
scanf("%d",&to);
maps[i].insert(maps[i].begin(),to);
}
}
solve();
fclose(stdin);
fclose(stdout);
return 0;
}