zoukankan      html  css  js  c++  java
  • 20180520模拟赛T1——math

    【问题描述】

    小美有 n 个点 m 条边。

    让你给每个点一个正整数编号。

    每条边有两个属性,相连的两个点的编号的 GCD 和 LCM。

    题目保证整张图连通。

    让你构造出一个编号。

    【输入格式】

    从文件 math.in 中读入数据。

    第一行两个正整数 n 和 m。

    接下去m行每行 4 个正整数 xi,yi,gcdi,lcmi。

    【输出格式】

    输出到文件 math.out 中。

    如果是有解:

    第一行一行 YES。

    第二行 n 个数字表示编号。

    否则输出一行NO。

    【样例】

    【样例输入】

    1 0

    【样例输出】

    YES 1

    【样例输入】

    2 1
    1 2 1 3

    【样例输出】

    YES 1 3

    【样例输入】

    3 2
    3 2 1 2
    3 1 1 10

    【样例输出】

    YES 5 1 2

    【样例输入】

    2 1
    1 2 3 7

    【样例输出】

    NO

    【数据规模】

    对于(100\%)的数据(2le n le 100,n-1 le m le n*(n-1)/2,1le gcdi, lcmi le 10^6)

    题解

    这题其实就是一道暴力题,是根据([a, b] imes (a, b) = a imes b)。已知(a imes b),暴力枚举(a),然后把整张图dfs一遍判断其正确性即可。

    不得不说:大力出奇迹!

    另外,记得开long long。

    题目加强版:CF 60C

    代码

    #include <cctype>
    #include <cstdio>
    #include <cstring>
    
    typedef long long LL;
    #define int long long
    
    #define dd c = getchar()
    inline void read(int& x)
    {
    	x = 0;
    	char dd;
    	bool f = false;
    	for(; !isdigit(c); dd)
    		if(c == '-')
    			x = -x;
    	for(; isdigit(c); dd)
    		x = (x<<1) + (x<<3) + (c^48);
    	if(f) x = -x;
    }
    #undef dd
    
    inline int gcd(int __n, int __m)
    {
    	while (__n)
    	{
    		int __t = __m % __n;
    		__m = __n;
    		__n = __t;
    	}
    	return __m;
    }
    
    const int maxn = 105;
    
    int n, m;
    
    int ans[maxn];
    
    struct edge
    {
    	LL cheng;
    	int t;
    	int ne;
    	int gcdd;
    } e[maxn*maxn];
    
    int first[maxn];
    bool vis[maxn];
    
    int mm;
    inline void add_edge(int f, int t, LL cheng, int gcdd) 
    {
    	e[++mm].ne = first[f];
    	e[mm].t = t;
    	e[mm].cheng = cheng;
    	e[mm].gcdd = gcdd;
    	first[f] = mm;
    
    	e[++mm].ne = first[t];
    	e[mm].t = f;
    	e[mm].cheng = cheng;
    	e[mm].gcdd = gcdd;
    	first[t] = mm;
    }
    
    inline bool dfs(int n, int last)//dfs检验答案正确性 
    {
    	vis[n] = true;
    	for(int i = first[n]; i; i = e[i].ne)
    	{
    		int to = e[i].t;
    		if(to == last) continue;
    		if(vis[to])
    		{
    			if((ans[to]*ans[n] != e[i].cheng) || (gcd(ans[to], ans[n]) != e[i].gcdd))
    				return false;
    		}
    		else
    		{
    			ans[to] = e[i].cheng / ans[n];
    			if(gcd(ans[to], ans[n]) != e[i].gcdd)
    				return false;
    			if(!dfs(to, n))
    				return false;
    		}
    	}
    	return true;
    }
    
    inline void print()
    {
    	puts("YES");
    	for(int i = 1; i <= n; ++i)
    		printf("%lld ", ans[i]);
    }
    
    inline void search()
    {
    	vis[1] = true;
    	if(!first[1])
    	{
    		puts("NO");
    		return;
    	}
    	LL k = e[first[1]].cheng;
    	for(int i = 1; i*i <= k; ++i)//暴力枚举所有可能情况 
    		if(!(k%i))
    		{
    			ans[1] = i;
    			memset(vis, 0, sizeof(vis));
    			if(dfs(1, 0))
    			{
    				print();
    				return;
    			}
    			ans[1] = k/i;
    			memset(vis, 0, sizeof(vis));
    			if(dfs(1, 0))
    			{
    				print();
    				return;
    			}
    		}
    	puts("NO");
    }
    
    signed main()
    {
    	freopen("math.in", "r", stdin);
    	freopen("math.out", "w", stdout);
    	scanf("%lld%lld", &n, &m);
    	if(n == 1)
    	{
    		puts("YES
    1");
    		return 0;
    	}
    	for(int i = 1; i <= m; ++i)
    	{
    		int f, t, gcdd, lcmm;
    		read(f), read(t), read(gcdd), read(lcmm);
    		add_edge(f, t, (LL)(gcdd*lcmm), gcdd);
    	}
    	search();
    	return 0;
    }
    
  • 相关阅读:
    ssh无密码登录设置
    Spark Standalone Mode 多机启动 -- 分布式计算系统spark学习(二)(更新一键启动slavers)
    Spark Standalone Mode 单机启动Spark -- 分布式计算系统spark学习(一)
    为golang程序使用pprof远程查看httpserver运行堆栈,cpu耗时等信息
    golang官方实现如何对httpserver做频率限制(最大连接数限制)
    【转】涨姿势了,数据库隔离性的几个级别
    loadRunner 11.0 安装及破解
    EF 如何code first
    百度搜索自动提示搜索相关内容----模拟实现
    如何写出专业级OOP程序-----文档注释
  • 原文地址:https://www.cnblogs.com/pfypfy/p/9064226.html
Copyright © 2011-2022 走看看