阅读 172

题解 NOIP2020 T1 排水系统

题解 NOIP2020 T1 排水系统

带 gcd 的纯模拟。( gcd 就是求最大公约数)

gcd 用来处理分数相加时的分母通分和分数的约分,

通过 gcd 珂以求出 lcm (最小公倍数):

lcm(x,y)=x×ygcd(x,y)lcm⁡(x,y)=x×ygcd(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;
}

第一次写题解,请多包涵。

服务器评测 http://www.cncsto.com/ 

服务器测评 http://www.cncsto.com/ 


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐