3287 货车运输
Posted 神犇(shenben)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3287 货车运输相关的知识,希望对你有一定的参考价值。
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。
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
3
-1
3
对于 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 点此展开
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; }
以上是关于3287 货车运输的主要内容,如果未能解决你的问题,请参考以下文章