求助,这里有比较详细的注释(但我怎么改代码,第五个到后面都过不了)
查看原帖
求助,这里有比较详细的注释(但我怎么改代码,第五个到后面都过不了)
395388
Code_Stu楼主2020/12/10 14:40
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<queue>
#define ll long long 
using namespace std;
typedef struct node
{
	int u;   //当前结点编号
	int p_n;   //它的排出管道的数量
	ll p,q;  //用于表示当前结点储存的污水量,p为分子,q为分母
	int *element;  //排出管道对应的结点 依次的编号
}Node;

Node a[100001];
int in_degree[100001];

ll gcd(ll a, ll b)    //求最大公因数
{ 
	return b == 0 ? a : gcd(b, a % b); 
}
ll lcm(ll a, ll b)  //求最小公倍数
{ 
	return a / gcd(a, b) * b; 
}

void Ave_Share( int u,int v )   //u为排水出发点的编号,v为接受污水结点的编号
{
	ll num,p_num_1,p_num_2;   //p_num_1、p_num_2分别为排水出发结点u 要分给结点为v的 污水量的分子和分母。
	if( a[v].p==0 )
	{
		if( a[u].p%a[u].p_n==0 )   //如果分子能够除得尽
		{
			a[v].p=a[u].p/a[u].p_n;
			a[v].q=a[u].q;
		}
		else
		{
		  a[v].p=a[u].p;
		  a[v].q=a[u].q*a[u].p_n;
		}
	}
	else
	{
		p_num_1=a[u].p;
		p_num_2=a[u].q*a[u].p_n;
	    num=lcm( p_num_2,a[v].q);   //求最小公倍数,交给num
	    p_num_1=(num / p_num_2)*p_num_1;
	    a[v].p =  (num / a[v].q)*a[v].p ;  //分子处理①
	    a[v].q = num;                     //分母处理
	    a[v].p += p_num_1;               //分子处理②
	    num=gcd( a[v].p,a[v].q );   //求使分子分母约到最简,需要同时除以的数,交给num
	    a[v].p/=num;
	    a[v].q/=num;
	}
}

int main()
{
	int n,m,i,j,d;         //n为排水结点数,m为接收口数量。d为排出管道的数量
	int index,k;
	queue<int> q;     //队列装结点编号  
	scanf("%d%d",&n,&m);
	for( i=1;i<=n;i++ )   //初始化
	{
		a[i].u=i;
		scanf("%d",&d);
		a[i].p_n=d;
		if( d!=0 )
		{
		  a[i].element=(int*)malloc(a[i].p_n*sizeof(int));
		  for( j=0;j<d;j++ )    //注意这里j是从0开始的
		  {
			scanf("%d",&a[i].element[j]);
			in_degree[ a[i].element[j] ]++;    //编号为a[i].element[j]的结点入度+1
		   }
		}
		a[i].p=a[i].q=0;     //每个结点的污水量初始化
	}
	for( i=1;i<=m;i++ )  //污水接收口一个一个地处理
	{
		a[i].p=a[i].q=1;   //污水流入该 表编号为i的 污水接收口
		q.push(a[i].u);
	}
	while( !q.empty() )  //只要队列还不为空
	{
		index=q.front();
		for( k=0;k<a[index].p_n;k++ )
		{
			in_degree[ a[index].element[k] ]--;      //编号为a[index].element[k]的结点的入度减1
			Ave_Share( index,a[index].element[k] );   //将该队头结点的污水均分掉
			if( in_degree[ a[index].element[k] ]==0 )   //如果入度为零,则可入队
			  q.push( a[index].element[k] );         
		}
		q.pop();
	}
	for( i=1;i<=n;i++ )
		if( a[i].p_n==0 )             
			printf("%lld %lld\n",a[i].p,a[i].q);
	return 0;
}

2020/12/10 14:40
加载中...