标签:它的 continue 输入格式 while 题目 sort 路径 UNC string
AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式:
第一行有两个用一个空格隔开的整数n,mn,m,表示 AA 国有nn 座城市和 mm 条道路。
接下来 mm行每行33个整数 x, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx号城市到yy号城市有一条限重为 zz 的道路。注意: xx 不等于 yy,两座城市之间可能有多条道路 。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。
输出格式:
共有 qq 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-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 }
标签:它的 continue 输入格式 while 题目 sort 路径 UNC string
原文地址:https://www.cnblogs.com/lcan/p/9623413.html