zoukankan      html  css  js  c++  java
  • P1967 货车运输

    题意

    题目描述

    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    输入输出格式

    输入格式:

    第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道
    路。

    接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为z的道路。注意:x不等于y,两座城市之间可能有多条道路。

    接下来一行有一个整数 q,表示有 q 辆货车需要运货。

    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。

    输出格式:

    输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
    车不能到达目的地,输出-1。

    说明

    对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;

    对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;

    对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。

    题解

    先跑最大圣城鼠,然后由于只剩一棵树,所以跑LCA记录路径上最小值就可以了

    然而图不一定联通...所以LCA预处理的时候要将每一个之前没有处理过的点跑一遍DFS

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    int n,m;
    struct A
    {
    	int from;
    	int to;
    	int val;
    }base[100100];
    int fa[100100];
    int to[100100],nex[100100],val[100100],head[100100],es;
    int f[10010][20],minn[10010][20],deep[10010],maxh;
    bool vis[10010];
    
    bool cmp(A a,A b){return a.val>b.val;}
    int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
    void max_set_tree()
    {
    	int nowin=0,u,v;
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++)
    		cin>>base[i].from>>base[i].to>>base[i].val;
    	sort(base+1,base+m+1,cmp);
    	for(int i=1;i<=m;i++)
    	{
    		u=base[i].from;
    		v=base[i].to;
    		u=find(u);
    		v=find(v);
    		if(u==v)
    			continue;
    		fa[u]=v;
    		++nowin;
    		to[++es]=v;
    		val[es]=base[i].val;
    		nex[es]=head[u];
    		head[u]=es;
    		to[++es]=u;
    		val[es]=base[i].val;
    		nex[es]=head[v];
    		head[v]=es;
    		if(nowin==n-1)
    			break;
    	}
    	deep[0]=-1;
    	return ;
    }
    
    void dfs(int now,int fa,int v)
    {
    	vis[now]=true;
    	deep[now]=deep[fa]+1;
    	f[now][0]=fa;
    	minn[now][0]=v;
    	for(int i=1;(1<<i)<=deep[now];i++)
    	{
    		f[now][i]=f[f[now][i-1]][i-1];
    		minn[now][i]=min(minn[now][i-1],minn[f[now][i-1]][i-1]);
    	}
    	for(int i=head[now];i;i=nex[i])
    		if(to[i]!=fa)
    			dfs(to[i],now,val[i]);
    	return ;
    }
    
    int lca(int x,int y)
    {
    	int res=2147483647;
    	if(deep[x]<deep[y])
    		swap(x,y);
    	for(int i=maxh;i>=0;i--)
    		if(deep[f[x][i]]>=deep[y])
    			res=min(res,minn[x][i]),x=f[x][i];
    	if(x==y)
    		return res;
    	for(int i=maxh;i>=0;i--)
    		if(f[x][i]!=f[y][i])
    		{
    			res=min(res,min(minn[x][i],minn[y][i]));
    			x=f[x][i];
    			y=f[y][i];
    		} 
    	res=min(res,min(minn[x][0],minn[y][0]));
    	return res;
    }
    
    void check()
    {
    	maxh=log(n)/log(2)+1;
    	int q,x,y;
    	cin>>q;
    	for(int i=1;i<=q;i++)
    	{
    		cin>>x>>y;
    		if(find(x)!=find(y))
    		{
    			cout<<-1<<endl;
    			continue;
    		}
    		else
    			cout<<lca(x,y)<<endl;
    	}
    }
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	max_set_tree();
    	for(int i=1;i<=n;i++)
    		if(!vis[i]) 
    			dfs(i,0,2147483647);
    	check();
    	return 0;
    } 
    

    吐槽

    我以后再也不写结构体了

    因为写了个结构体,WA了还找不出错来...

  • 相关阅读:
    哥java学识有大进 干回之前的小学生系统像切菜一样简单 不说了 来代码
    祝贺自己操作系统JAVA项目有进展!!
    四则运算的开发
    四则运算app总结
    对其它组评价的反馈
    第三次spring冲刺2
    阅读《构建之法》第13-17章
    对其他组的评价
    第三次spring冲刺1
    阅读11,12章
  • 原文地址:https://www.cnblogs.com/Alarak26/p/9278497.html
Copyright © 2011-2022 走看看