码迷,mamicode.com
首页 > 其他好文 > 详细

3287 货车运输

时间:2016-07-02 18:48:10      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

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。

 
 
技术分享

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(){
    freopen("sh.in","r",stdin);
    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<iostream>
#include<vector>
using namespace std;
#define N 10010
int n,m,q,fa[N],dfn[N],deep[N];
vector<int>p[N],c[N];
struct node{
    int u,v,w;
}s[5*N];
struct ss{
    int p,c;
}f[N][51];
inline bool cmp(const node & x,const node & y){
    return x.w>y.w;
}
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void tarjan(int k,int de){
    deep[k]=de;
    dfn[k]=1;
    for(int i=1;(1<<i)<=deep[k];i++){
        f[k][i].p=f[f[k][i-1].p][i-1].p;
        f[k][i].c=min(f[k][i-1].c,f[f[k][i-1].p][i-1].c);
    }
    for(int i=0;i<p[k].size();i++){
        if(!deep[p[k][i]]){
            f[p[k][i]][0].p=k;
            f[p[k][i]][0].c=c[k][i];
            tarjan(p[k][i],de+1);
        }
    }
}
int lca(int a,int b)
{
    if (deep[a]<deep[b]) swap(a,b);
    int t=deep[a]-deep[b];
    int ans=0x7fffffff; 
    for(int i=0;i<=20;i++){
        if((1<<i)&t){
            ans=min(f[a][i].c,ans);
            a=f[a][i].p; 
        }
    }     
    for(int i=20;i>=0;i--){
        if(f[a][i].p!=f[b][i].p){
            ans=min(f[b][i].c,ans);
            ans=min(f[a][i].c,ans);
            a=f[a][i].p;
            b=f[b][i].p;        
        }
    }    
    if(a==b) return ans;
    else return min(f[a][0].c,min(f[b][0].c,ans));                         
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&s[i].u,&s[i].v,&s[i].w);
    }
    for(int i=1;i<=n;i++) fa[i]=i;
    sort(s+1,s+m+1,cmp);
    for(int i=1;i<=m;i++){
        int fx=find(s[i].u),fy=find(s[i].v);
        if(fx!=fy){
            fa[fx]=fy;
            p[s[i].u].push_back(s[i].v);
            p[s[i].v].push_back(s[i].u);
            c[s[i].u].push_back(s[i].w);
            c[s[i].v].push_back(s[i].w);
             
        }
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]) tarjan(i,1);
    }
    scanf("%d",&q);
    for(int i=1,x,y;i<=q;i++){
        scanf("%d%d",&x,&y);
        if(find(x)!=find(y)) puts("-1");
        else printf("%d\n",lca(x,y));
    }
    return 0;
}

 

 

 

3287 货车运输

标签:

原文地址:http://www.cnblogs.com/shenben/p/5635712.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!