zoukankan      html  css  js  c++  java
  • 2019CSP-J T4 加工零件

    题目描述

    凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇。工厂里有 n 位工人,工人们从 1 n 编号。某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带。

    如果 x 号工人想生产一个被加工到第 L(L>1) 阶段的零件,则所有与 x 号工人有传送带直接相连的工人,都需要生产一个被加工到第 L - 1 阶段的零件(但 x 号工人自己无需生产第 L - 1 阶段的零件)。

    如果 x 号工人想生产一个被加工到第 1 阶段的零件,则所有与 x 号工人有传送带直接相连的工人,都需要为 x 号工人提供一个原材料。

    轩轩是 1 号工人。现在给出 q 张工单,第 i 张工单表示编号为 ai 的工人想生产一个第 Li 阶段的零件。轩轩想知道对于每张工单,他是否需要给别人提供原材料。他知道聪明的你一定可以帮他计算出来!

    输入格式

    第一行三个正整数 nm 和 q,分别表示工人的数目、传送带的数目和工单的数目。

    接下来 m 行,每行两个正整数 u 和 v,表示编号为 u 和 v 的工人之间存在一条零件传输带。保证 u 不等于 v。

    接下来 q 行,每行两个正整数 a 和 L,表示编号为 a 的工人想生产一个第 L 阶段的零件。

    输出格式

    共 q 行,每行一个字符串 Yes 或者 No。如果按照第 i 张工单生产,需要编号为 1 的轩轩提供原材料,则在第 i 行输出 Yes;否则在第 i 行输出 No。注意输出不含引号。

    正文开始:

    这个题不难看出(我当时死活没看出来)是个奇偶数最短路(瞎起的名字),大体意思就是,一个位置要单数零件,和他相邻单数长度且长度不超过零件等级的位置都要提供原料。(想象2个工人互相给零件,距离原点的距离和原点零件等级跟最后谁做原零件都是有关系的)

    我们可以用链式前向星建图,广搜遍历,每到达一个新的点还要判断这次的距离是不是更短,要把距离1号点的奇偶数距离记成最小的。不可以只记有没有,万一1号点做2号零件,你距离1号点100格远,肯定用不到你。对了,广搜有个剪枝,如果这个点的奇偶距离都没变,哪继续求就没意义了,之前肯定进过队列,所以直接抛弃它。

    一号点可以和任何一个相邻的点循环给零件,所以一号点距离1号点的初始值是0。(为什么不能是2,又不会制作等级0的零件? 因为要根据1号点距离自己的偶数位置求其他点的奇数位置。)

    上一句话有个地方有点重要(任何一个相邻的点),重点不是任何,是相邻的点,我们要特判,如果一号没有相邻的点,输入什么都输出0。上面的初始偶数距离是0也不管用。

    可能会奇妙的转圈圈,所以奇偶数的初始值要定义的很大。

    差不多就这样,不会链式前向星的同学可以去翻看之前的博客

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<cstring>
    using namespace std;
    queue<long long>bj;
    long long shu=1,a[100005],p,n,m,z1,z2,ji[100005],ou[100005],f;
    struct hehe
    {
    	long long w,nxt;
    }sz[200005];
    void add(long long z1,long long z2)
    {
    	sz[shu].nxt=a[z1];
    	sz[shu].w=z2;
    	a[z1]=shu;
    	shu++;
    }
    void bfs()
    {
    	bj.push(1);
    	ou[1]=0;
    	while(bj.empty()!=true)
    	{
    		long long bl=bj.front();
    		bj.pop();
    		for(long long i=a[bl];i!=0;i=sz[i].nxt)
    		{
    			if(ou[bl]+1<ji[sz[i].w]||ji[bl]+1<ou[sz[i].w])
    			{
    				bj.push(sz[i].w);
    			}
    			ji[sz[i].w]=min(ji[sz[i].w],ou[bl]+1);
    			ou[sz[i].w]=min(ou[sz[i].w],ji[bl]+1);
    		}
    	}
    }
    int main()
    {
    	scanf("%lld%lld%lld",&n,&m,&p);
    	for(long long i=1;i<=100005;i++)
    	{
    		ji[i]=99999999;
    		ou[i]=99999999;
    	}
    	for(long long i=0;i<m;i++)
    	{
    		scanf("%lld%lld",&z1,&z2);
    		add(z1,z2);
    		add(z2,z1);
    		if(z1==1||z2==1)
    		{
    			f=1;
    		}
    	}
    	bfs();
    	for(long long i=0;i<p;i++)
    	{
    		scanf("%lld%lld",&z1,&z2);
    		if(f!=1)
    		{
    			cout<<"No"<<endl;
    			continue;
    		}
    		if(ou[z1]<=z2&&z2%2==0)
    		{
    			cout<<"Yes"<<endl;
    			continue;
    		}
    		if(ji[z1]<=z2&z2%2==1)
    		{
    			cout<<"Yes"<<endl;
    			continue;
    		}
    		cout<<"No"<<endl;
    	}
    	return 0;
    }

     当时可能傻了吧。

  • 相关阅读:
    SQL Server 限制IP登陆
    提高MSSQL数据库读取速度,降低CPU损耗
    Windows Azure 平台开发基础系列视频
    AutoFac使用方法总结:Part III
    Python学习笔记 01 快速入门
    黑苹果~~
    Python学习笔记 02 Python基础
    Python学习笔记 04 数字
    Python学习笔记 03 Python对象
    Gridview导出excel范例
  • 原文地址:https://www.cnblogs.com/lichangjian/p/12572029.html
Copyright © 2011-2022 走看看