NOIP2020 T1 water

mulu


感觉难度还是很高的,膜拜大佬们


具体题目


题目解法

难啊,自己开始看到这道题直接上头了,因为题目的样子实在是,哎……所以开始搞暴力,因为自己也不会啊。先是这道第一题,发现可以满分???
拓扑&&BFS?
不知道,但是自己比赛的时候只开始了 D F S DFS DFS。
然后一大堆迷惑操作,还是大样例太水了,所以过了。
这时候,比赛开始一个小时了。看了看捋了捋自己的做法:因为看到数据上面说每个排水点中转站总数是不会超过10个的,所以开始从每一个排水点开始递归,发现问题严重啊。
开始乱改:

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
long long n,m;
_int128 arr,d[5005],ans[5005][5005];
bool bz[5005][5005],bj[5005];
long long pc[5005],add[5005];
void dg(long long root,long long x,long long y)
{
	if(add[x]==true)
	{
		ans[root][++ans[root][0]]=y;
		return ;	
	}
	for(long long i=1;i<=n;++i)
		if(bz[i][x]==true)
			dg(root,i,y*d[i]);
}
long long gcd(long long x,long long y)
{
	if(x<y){long long t=x;x=y,y=t;}
	if(x%y==0) return y;
	return gcd(y,x%y);
}
int main()
{
	memset(bz,false,sizeof(bz));
	memset(bj,false,sizeof(bj));
	scanf("%lld%lld",&n,&m);
	bool bj[3005];
	for(long long i=1;i<=n;++i)
	{
		scanf("%lld",&d[i]);
		for(long long j=1;j<=d[i];++j)
		{
			scanf("%lld",&arr);
			bz[i][arr]=true;
			bj[arr]=true;
		}
		if(d[i]==0) pc[++pc[0]]=i;
	}
	for(long long i=1;i<=n;++i)
		if(bj[i]==false)
			add[i]=true;
	for(long long i=1;i<=pc[0];++i)
		dg(pc[i],pc[i],1);
	for(long long i=1;i<=n;++i)
		if(ans[i][0]>0)
		{
			long long sum=ans[i][1],kk,sum2=0;
			for(long long j=2;j<=ans[i][0];++j)
			{
				kk=gcd(sum,ans[i][j]);
				sum*=ans[i][j]/kk;
			}
			for(long long j=1;j<=ans[i][0];++j)
				sum2+=sum/ans[i][j];
			kk=gcd(sum2,sum);
			printf("%lld %lld\n",sum2/kk,sum/kk);
		}
	return 0;
}
上一篇:WebSocket 理解


下一篇:BZOJ1218激光炸弹