zoukankan      html  css  js  c++  java
  • csp练习

    21次

    04-食材运输

    思路:
    首先看30%的部分。
    检查点数量与运输车数量相同,并且保证图是一条链。
    把检查点设置在每辆运输车的出发点。
    每辆食材运输车的路径就是,需要这种食材的酒店中,从最左边的那个出发,到最右边的那个结束。
    路径中的最长等待时间就是路径的长度。
    所以答案是所有路径长度中的最大值。


    70%部分。
    检查点数量与运输车数量相同。
    与30%的相同,把检查点设置在每辆运输车的出发点,无需考虑检查点位置。

    若出发点为x,我们将需要运送该食材的所有点与x相连,可以得到一棵树,
    我们可以发现,除了最后到达的节点与x之间的边(只经过一次),所有的边都会被经过两次。
    假设这棵树上所有路径的总长为DIS,最后一个到达的点为y,那么这次运送中的最长等待时间就是2DIS-dis[y]
    而对于最小的最大等待时间,就是2DIS-max_dis

    于是枚举每辆运输车,枚举每个点为这辆运输车的出发点x,
    然后以x为出发点进行搜索,求出DIS和max_dis。
    统计枚举每个出发点中得到的2DIS-max_dis的最小值ans,
    然后再统计每辆运输车中最长等待时间的最大值ANS。


    (说好的70分呢,似乎把样例1特判一下还有5分)
    下面是参考代码,注释有点乱。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=105;
    int num,to[maxn<<1],nxt[maxn<<1],w[maxn<<1],last[maxn],dis[maxn],DIS,Max_dis; 
    int need[maxn][12];
    void clear(){
    	num=0;
    	memset(last,-1,sizeof(last));
    }
    void insert(int x,int y,int z){
    	to[++num]=y;
    	nxt[num]=last[x];
    	last[x]=num;
    	w[num]=z;
    }
    bool dfs(int x,int pre,int fd){ 
    	int i,y;
    	bool re=false;
    	if (need[x][fd]) re=true;
    	//x需要运送食材fd,标记边(pre,x)
    	for (i=last[x];i!=-1;i=nxt[i]){ 
    		y=to[i];
    		if (y==pre) continue;//不走回头路 
    		dis[y]=dis[x]+w[i];//记录y与根节点的距离 
    		if (dfs(y,x,fd)) {
    			DIS+=w[i]; 
    			//将标记路径加入总路径
    			Max_dis=max(Max_dis,dis[y]);
    			//记录标记路径上距离根节点最远的节点距离 
    			re=true;
    			//由于x的子节点需要运送,标记边(pre,x) 
    		}
    	}
    	return re;
    }
    int main(){
    	int n,m,k,i,j,x,y,z;
    	int now,ans,ANS;
    	scanf("%d%d%d",&n,&m,&k);
    	for (i=1;i<=n;i++){
    		for (j=1;j<=k;j++){
    			scanf("%d",&need[i][j]);
    		}
    	}
    	clear();
    	for (i=1;i<n;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		insert(x,y,z);
    		insert(y,x,z);
    	}//建图 
    	ANS=0;
    	for (i=1;i<=k;i++){//枚举每种每辆食材运输车 
    		ans=-1;//用于统计枚举出发点位置过程中,最大等待时间的最小值 
    		for (j=1;j<=n;j++){//枚举出发点位置 
    			dis[j]=0; 
    			DIS=0;
    			Max_dis=0;
    			dfs(j,j,i);
    			/*
    			dfs作用:以j为根节点,
    			计算所有需要运送食材i的节点与j连接后,得到的树中所有边之和DIS, 
    			并记录所有需要运送食材i的节点距离根节点j的路径的最大值Max_dis 
    			*/ 
    			now=2*DIS-Max_dis;//得到的最小的最大等待时间 
    			if (ans==-1 || now<ans) ans=now;  
    		}
    		if (ans>ANS) ANS=ans;//ANS用于记录所有食材运输车中最大等待时间的最大值 
    	}
    	printf("%d
    ",ANS);
    	return 0; 
    }
    
  • 相关阅读:
    【正则】限定符-总
    【正则】字符类-总
    【正则】元字符-总
    【正则】基本知识点
    Linux 核心系统命令目录
    股票模型
    windows 批量删除用户
    cka 英文考试题
    cka 英文考试题
    李永乐说股票
  • 原文地址:https://www.cnblogs.com/lsykk/p/15230722.html
Copyright © 2011-2022 走看看