• 货车运输


    题目描述

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

    输入输出格式

    输入格式:

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

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

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

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

    输出格式:

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

    就是每条路径上取一个最小值,有多条路径时取一个最大值,但对每组询问都跑一边SPFA肯定是不对的。

    然后看了标签,就是求一个最大生成树,然后用倍增维护最小值......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=1e4+7;
     7 const int maxm=5e4+7;
     8 int n,m,num,q,ans,tot;
     9 int head[maxn],fa[maxn],dep[maxn],f[maxn][27],imin[maxn][27];
    10 struct E{
    11   int from,to,dis;
    12 }e[maxm];
    13 struct Edge{
    14   int next,to,dis;
    15 }edge[maxm];
    16 void add(int from,int to,int dis){
    17   edge[++num].next=head[from];
    18   edge[num].to=to;
    19   edge[num].dis=dis;
    20   head[from]=num; 
    21 }
    22 bool cmp(E a,E b){return a.dis>b.dis;}
    23 int find(int x){
    24   if(fa[x]==x) return x;
    25   return fa[x]=find(fa[x]);
    26 }
    27 void merge(int x,int y){
    28  int fx=find(x);int fy=find(y);
    29  if(fx!=fy) fa[fx]=fy;
    30 }
    31 void kruskal(){
    32   int cnt=0;
    33   for(int i=1;i<=n;i++) fa[i]=i;
    34   for(int i=1;i<=tot;i++){
    35     int u=e[i].from;int v=e[i].to;
    36     int fu=find(u);int fv=find(v);
    37     if(fu!=fv){
    38       merge(fu,fv);cnt++;
    39       add(u,v,e[i].dis);add(v,u,e[i].dis);
    40     }
    41     if(cnt==n-1) return;
    42   }
    43 }
    44 void prepare(int x,int pre){
    45   dep[x]=dep[pre]+1;
    46   for(int i=1;i<=19;i++){
    47     f[x][i]=f[f[x][i-1]][i-1];
    48     imin[x][i]=min(imin[x][i-1],imin[f[x][i-1]][i-1]);
    49   }
    50   for(int i=head[x];i;i=edge[i].next){
    51     int v=edge[i].to;
    52     if(v==pre) continue;
    53     f[v][0]=x;imin[v][0]=edge[i].dis;
    54     prepare(v,x);
    55   }
    56 }
    57 void process(int x,int y){
    58   int ans1=0x7f7f7f7f;int ans2=0x7f7f7f7f;
    59   if(dep[x]<dep[y]) swap(x,y);
    60   for(int i=20;i>=0;i--){
    61     if(dep[f[x][i]]>=dep[y]){ans=min(ans1,imin[x][i]);x=f[x][i];}
    62   }
    63   if(x==y){ans=min(ans1,ans2);return;}
    64   for(int i=20;i>=0;i--){
    65     if(f[x][i]!=f[y][i]){
    66       ans1=min(ans1,imin[x][i]);ans2=min(ans2,imin[y][i]);
    67       x=f[x][i];y=f[y][i];
    68     }
    69   }
    70   ans1=min(ans1,imin[x][0]);ans2=min(ans2,imin[y][0]);
    71   ans=min(ans1,ans2);return;
    72 }
    73 int main(){
    74   cin>>n>>m;
    75   for(int i=1;i<=n;i++){
    76     int x,y,w;cin>>x>>y>>w;
    77     e[++tot].from=x;e[tot].to=y;e[tot].dis=w;
    78   }
    79   sort(e+1,e+tot+1,cmp);
    80   kruskal();
    81   memset(imin,0x7f7f7f7f,sizeof(imin));
    82   prepare(1,0);
    83   cin>>q;
    84   while(q--){
    85     int x,y;cin>>x>>y;
    86     ans=0x7f7f7f7f;process(x,y);
    87     if(ans==0x7f7f7f7f) cout<<"-1"<<endl;
    88     else cout<<ans<<endl;
    89   }
    90   return 0;
    91 }

     上面没有考虑多棵树

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 typedef long long ll;
      7 const int maxn=1e4+7;
      8 const int maxm=5e4+7;
      9 ll n,m,num,q,ans,tot;
     10 ll head[maxn],fa[maxn],dep[maxn],f[maxn][27],imin[maxn][27];
     11 struct E{
     12   int from,to,dis;
     13 }e[maxm];
     14 struct Edge{
     15   int next,to,dis;
     16 }edge[maxm];
     17 void add(int from,int to,int dis){
     18   edge[++num].next=head[from];
     19   edge[num].to=to;
     20   edge[num].dis=dis;
     21   head[from]=num; 
     22 }
     23 bool cmp(E a,E b){return a.dis>b.dis;}
     24 int find(int x){
     25   if(fa[x]==x) return x;
     26   return fa[x]=find(fa[x]);
     27 }
     28 void merge(int x,int y){
     29  int fx=find(x);int fy=find(y);
     30  if(fx!=fy) fa[fx]=fy;
     31 }
     32 void kruskal(){
     33   int cnt=0;
     34   for(int i=1;i<=n;i++) fa[i]=i;
     35   for(int i=1;i<=tot;i++){
     36     int u=e[i].from;int v=e[i].to;
     37     int fu=find(u);int fv=find(v);
     38     if(fu!=fv){
     39       merge(fu,fv);cnt++;
     40       add(u,v,e[i].dis);add(v,u,e[i].dis);
     41     }
     42     if(cnt==n-1) return;
     43   }
     44 }
     45 void prepare(int x,int pre){
     46   dep[x]=dep[pre]+1;
     47   for(int i=1;i<=19;i++){
     48       if(f[x][i-1]==0) break;
     49     f[x][i]=f[f[x][i-1]][i-1];
     50     imin[x][i]=min(imin[x][i-1],imin[f[x][i-1]][i-1]);
     51   }
     52   for(int i=head[x];i;i=edge[i].next){
     53     int v=edge[i].to;
     54     if(v==pre) continue;
     55     f[v][0]=x;imin[v][0]=edge[i].dis;
     56     prepare(v,x);
     57   }
     58 }
     59 bool process(int x,int y){
     60   ll ans1=0x7f7f7f7f;ll ans2=0x7f7f7f7f;
     61   if(dep[x]<dep[y]) swap(x,y);
     62   for(int i=20;i>=0;i--){
     63     if(dep[f[x][i]]>=dep[y]){ans1=min(ans1,imin[x][i]);x=f[x][i];}
     64   }
     65   if(x==y){ans=min(ans1,ans2);return true;}
     66   for(int i=20;i>=0;i--){
     67     if(f[x][i]!=f[y][i]){
     68       ans1=min(ans1,imin[x][i]);ans2=min(ans2,imin[y][i]);
     69       x=f[x][i];y=f[y][i];
     70     }
     71   }
     72   if(f[x][0]!=f[y][0]) return false;//因为是取最小值,所以INF会被忽略 
     73   else{
     74     ans1=min(ans1,imin[x][0]);ans2=min(ans2,imin[y][0]);
     75     ans=min(ans1,ans2);return true;
     76   }
     77 }
     78 int main(){
     79   cin>>n>>m;
     80   for(int i=1;i<=m;i++){
     81     int x,y,w;cin>>x>>y>>w;
     82     e[++tot].from=x;e[tot].to=y;e[tot].dis=w;
     83   }
     84   sort(e+1,e+tot+1,cmp);
     85   kruskal();
     86   memset(imin,0x7f7f7f7f,sizeof(imin));
     87   prepare(1,0);f[1][0]=1;
     88   for(int i=1;i<=n;i++){
     89     if(dep[i]==0) {prepare(i,0);f[i][0]=i;}
     90   }
     91   cin>>q;
     92   for(int i=1;i<=q;i++){
     93     int x,y;cin>>x>>y;
     94     ans=0x7f7f7f7f;
     95     if(!process(x,y)) cout<<"-1"<<endl;
     96     else if(ans==0x7f7f7f7f) cout<<"-1"<<endl;
     97     else cout<<ans<<endl;
     98   }
     99   return 0;
    100 }
  • 相关阅读:
    Echarts关于仪表盘
    Echarts CPU监控 (折线仪表盘,图例混搭)
    物联网温度服务器-ECharts、HTML5、JavaScript / ECharts gauge使用示例
    eCharts使用图表简单示例
    Andorid之ActivityManager
    IOS之NSFileManager 和NSFileHandle
    IOS UITableView多选删除功能
    IOS Xib使用——Xib表示局部界面
    Android典型界面设计(8) ——ViewPager+PagerSlidingTabStrip实现双导航
    IOS程式语法之block的使用掌握
  • 原文地址:https://www.cnblogs.com/lcan/p/9623413.html
Copyright © 2020-2023  润新知