当前位置: 首页 > news >正文

3287 货车运输

3287 货车运输

 

2013年NOIP全国联赛提高组

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
题解
 
 
 
题目描述  Description

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

输入描述  Input Description

第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

输出描述  Output Description

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

样例输入  Sample Input

4 3 
1 2 4 
2 3 3 
3 1 1 
3
1 3 
1 4 
1 3

样例输出  Sample Output

3
-1
3

数据范围及提示  Data Size & Hint

对于 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。

分类标签 Tags 点此展开 

 
最小生成树  图论  大陆地区  NOIP全国联赛提高组  2013年
 
 

20分代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 5001
int g[N][N];
int n,m,q;
int main(){
    
    scanf("%d%d",&n,&m);
    memset(g,-1,sizeof g);
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        g[x][y]=max(g[x][y],z);
        g[y][x]=max(g[y][x],z);
    }
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i!=j&&g[i][k]!=-1&&g[k][j]!=-1){
                    g[i][j]=max(g[i][j],min(g[i][k],g[k][j]));
                }
            }
        }
    }
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",g[x][y]);
    }
    return 0;
}

朴素LCA的AC代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10010
int n,m,q,fa[N],fv[N],vi[N],s[N][51],v[N][51];
struct node{
    int x,y,s;
}a[N*5];
inline bool cmp(const node &q,const node &p){
    return q.s>p.s;
}
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void dfs(int x){
    for(int i=1;i<=s[x][0];i++){
        if(fa[s[x][i]]==s[x][i]){
            fa[s[x][i]]=x;
            fv[s[x][i]]=v[x][i];
            dfs(s[x][i]);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].s);
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        int fx=find(a[i].x),fy=find(a[i].y);
        if(fx!=fy){
            fa[fx]=fy;
            s[a[i].x][++s[a[i].x][0]]=a[i].y;
            s[a[i].y][++s[a[i].y][0]]=a[i].x;
            v[a[i].x][++v[a[i].x][0]]=a[i].s;
            v[a[i].y][++v[a[i].y][0]]=a[i].s;
        }
    }
    for(int i=1;i<=n;i++) fa[i]=i;
    fa[1]=0;
    dfs(1);
    scanf("%d",&q);
    for(int i=1,x,y;i<=q;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++) vi[j]=1e8;
        for(int j=x;vi[fa[j]]==1e8&&j;j=fa[j])
            vi[fa[j]]=min(vi[j],fv[j]);
        int tmp=1e8;
        for(int j=y;;j=fa[j]){
            if(vi[j]<1e8||j==x){
                tmp=min(tmp,vi[j]);break;
            }
            tmp=min(tmp,fv[j]);
            if(fa[j]==j||!j){tmp=-1;break;}
        }
        if(!tmp) tmp=-1;
        printf("%d\n",tmp);
    }
    return 0;
}

 

 

 

倍增LCA就是快!

AC代码:

 

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define N 10100
inline const int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,q,fa[N],dep[N],f[N][21],g[N][21];
struct node{
    int u,v,w;
    bool operator < (const node &t) const {return w>t.w;}
}e[N<<1];
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
vector<int>p[N],c[N];
void dfs(int x,int de){
    for(int i=0;i<p[x].size();i++){
        if(!dep[p[x][i]]){
            dep[p[x][i]]=de+1;
            f[p[x][i]][0]=x;
            g[p[x][i]][0]=c[x][i];
            dfs(p[x][i],de+1);
        }
    }
}
int lca(int a,int b){
    if(dep[a]<dep[b]) swap(a,b);
    int t=dep[a]-dep[b];
    int ans=0x7fffffff;
    for(int i=0;i<=20;i++){
        if((1<<i)&t){
            ans=min(ans,g[a][i]);
            a=f[a][i];
        }
    }
    if(a==b) return ans;
    for(int i=20;i>=0;i--){
        if(f[a][i]!=f[b][i]){
            ans=min(ans,g[a][i]);
            ans=min(ans,g[b][i]);
            a=f[a][i];
            b=f[b][i];
        }
    }
    return min(ans,min(g[a][0],g[b][0]));
}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(),e[i].w=read();
    for(int i=1;i<=n;i++) fa[i]=i;
    stable_sort(e+1,e+m+1);
    for(int i=1;i<=m;i++){
        int fx=find(e[i].u),fy=find(e[i].v);
        if(fx!=fy){
            fa[fx]=fy;
            p[e[i].u].push_back(e[i].v);
            p[e[i].v].push_back(e[i].u);
            c[e[i].u].push_back(e[i].w);
            c[e[i].v].push_back(e[i].w);
        }
    }
    dep[1]=1;
    dfs(1,1);
    for(int j=1;j<=20;j++){
        for(int i=1;i<=n;i++){
            f[i][j]=f[f[i][j-1]][j-1];
            g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]);
        }
    }
    q=read();
    for(int i=1,x,y,tmp;i<=q;i++){
        x=read();y=read();
        if(find(x)!=find(y)){puts("-1");continue;}
        printf("%d\n",lca(x,y));
    }
    return 0;
}

 2017-04-06

/最小值最大:最大生成树找最小边 
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=1e4+5;
const int M=1e5+5;
int n,m,Q,fa[N],dep[N],f[N][20],g[N][20];
struct data{int u,v,w;}a[M];
struct edge{int v,w,next;}e[M];int tot,head[N];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
bool operator <(const data &a,const data &b){
    return a.w>b.w;
}
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void add(int x,int y,int z){
    e[++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
    e[++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
}
void dfs(int x){
    for(int i=head[x];i;i=e[i].next){
        if(!dep[e[i].v]){
            dep[e[i].v]=dep[x]+1;
            f[e[i].v][0]=x;
            g[e[i].v][0]=e[i].w;
            dfs(e[i].v);
        }
    }
}
int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    int t=dep[x]-dep[y],ans=2e9;
    for(int i=0;i<=18;i++){
        if(t&(1<<i)){
            ans=min(ans,g[x][i]);
            x=f[x][i];
        }
    }
    if(x==y) return ans;
    for(int i=18;~i;i--){
        if(f[x][i]!=f[y][i]){
            ans=min(ans,g[x][i]);
            ans=min(ans,g[y][i]);
            x=f[x][i];
            y=f[y][i];
        }
    }
    return min(ans,min(g[x][0],g[y][0]));
}
int main(){
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++) a[i].u=read(),a[i].v=read(),a[i].w=read();
    sort(a+1,a+m+1);
    for(int i=1,k=0,x,y,fx,fy;i<=m;i++){
        x=a[i].u,y=a[i].v;
        fx=find(x);fy=find(y);
        if(fx!=fy){
            fa[fx]=fy;
            add(x,y,a[i].w);
            if(++k==n-1) break;
        }
    }
    dep[1]=1;dfs(1);
    for(int j=1;j<=18;j++){
        for(int i=1;i<=n;i++){
            f[i][j]=f[f[i][j-1]][j-1];
            g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]);
        }
    }
    Q=read();
    for(int i=1,x,y;i<=Q;i++){
        x=read();y=read();
        if(find(x)!=find(y)) puts("-1");
        else printf("%d\n",lca(x,y));
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/shenben/p/5635712.html

相关文章:

  • Windows SQL2008数据库系列一数据的导入导出
  • dataTable 查询,重置
  • Jsoup学习总结
  • 工作步骤
  • linux分区,磁盘系统的管理,文件系统制作
  • H5上传图片前端预览显示
  • 大型企业网络配置系列课程详解(六) --PPP链路的配置与相关概念的理解
  • 2、使用vmware虚拟机安装Linux(以redhat5.8为例)中常见问题
  • C字符串与NSString之间的转换
  • 集合(三)CopyOnWriteArrayList
  • linux基础,zip、tar
  • http基本概述
  • 解决FTP服务器命令好使,工具不好使。
  • 学习计划与方法
  • go语言笔记——go环境变量goroot是安装了路径和gopath是三方包路径
  • [译]Python中的类属性与实例属性的区别
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【刷算法】求1+2+3+...+n
  • 78. Subsets
  • create-react-app项目添加less配置
  • git 常用命令
  • IDEA 插件开发入门教程
  • Java 网络编程(2):UDP 的使用
  • JDK 6和JDK 7中的substring()方法
  • Python十分钟制作属于你自己的个性logo
  • Redis的resp协议
  • session共享问题解决方案
  • socket.io+express实现聊天室的思考(三)
  • Transformer-XL: Unleashing the Potential of Attention Models
  • Vim 折腾记
  • 爱情 北京女病人
  • 彻底搞懂浏览器Event-loop
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 从零开始在ubuntu上搭建node开发环境
  • 分布式事物理论与实践
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 批量截取pdf文件
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 事件委托的小应用
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • $.ajax()参数及用法
  • (12)Hive调优——count distinct去重优化
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET 设计一套高性能的弱事件机制
  • .net 托管代码与非托管代码
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表