P1967 freight car transportation, p1967 freight car transportation
Description
A has n cities in China, ranging from 1 to n. There are m two-way roads between cities. Each road imposes weight limitations on vehicles. Now there are q trucks carrying goods. drivers want to know that each truck can carry a maximum of multiple goods without exceeding the vehicle weight limit.
Input/Output Format
Input Format:
The input file name is truck. in.
The first line of the input file contains two integers n, m separated by A space, indicating n cities and m channels in.
Path. Next, line m contains three integers x, y, and z in each row. Each integer is separated by a space, which indicates that there is a road with a limited weight of z from city x to city y. Note:X is not equal to y. There may be multiple roads between two cities..
The next line contains an integer q, indicating that a truck needs to deliver the goods.
Next, in row q, two integers x and y are separated by a space, indicating that a freight car needs to transport goods from city x to city y. Note:X is not equal to y.
Output Format:
The output file name is truck. out.
The output contains a total of q rows. Each line has an integer representing the maximum load of each truck. If the goods
The vehicle cannot reach the destination. Output-1.
Input and Output sample
Input example #1:
4 31 2 42 3 33 1 131 31 41 3
Output sample #1:
3-13
Description
For 30% of data, 0 <n <1,000, 0 <m <10,000, 0 <q <1,000;
For 60% of data, 0 <n <1,000, 0 <m <50,000, 0 <q <1,000;
For 100% of data, 0 <n <10,000, 0 <m <50,000, 0 <q <30,000, 0 ≤ z ≤ 100,000.
After fighting for this question for a total of 7.5 hours, I finally debugged it !!
I will not talk much about the idea. I just need to run one side of the tree and multiply it to find the LCA and keep getting the minimum value.
Here I will introduce the mistakes that are easy to make.
1. When reading the first graph, you must store it with a directed edge. However, the graph generated by running the maximum spanning tree must be stored in an undirected graph.
2. When selecting the source point, you can perform dfs from 1-> n, but you must open a vis array. It is not possible to simply use a deep array.
3. When jumping from a low point to a high point, the judgment condition must be deep [s [x] [I]> = deep [y], which must be >= !!!
4. The minimum value must be obtained before the variable is updated !!
5. Pay attention to initialization of various variables!
Because the debugging time is relatively long, the code can be relatively long, but there are no high-level statements, the writing is still simple
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN=50001; 8 int n,m; 9 int x,y,z; 10 int vis[MAXN]; 11 struct node 12 { 13 int u,v,w,next; 14 }edge[MAXN],a[MAXN]; 15 int num=1; 16 int head[MAXN]; 17 int f[MAXN]; 18 int anum=1; 19 int ahead[MAXN]; 20 int deep[MAXN]; 21 int s[MAXN][20]; 22 int take[MAXN][20]; 23 void edge_add(int x,int y,int z) 24 { 25 edge[num].u=x; 26 edge[num].v=y; 27 edge[num].w=z; 28 edge[num].next=head[x]; 29 head[x]=num++; 30 } 31 void a_add(int i) 32 { 33 a[anum].u=edge[i].u; 34 a[anum].v=edge[i].v; 35 a[anum].w=edge[i].w; 36 a[anum].next=ahead[a[anum].u]; 37 ahead[a[anum].u]=anum++; 38 a[anum].u=edge[i].v; 39 a[anum].v=edge[i].u; 40 a[anum].w=edge[i].w; 41 a[anum].next=ahead[a[anum].u]; 42 ahead[a[anum].u]=anum++; 43 } 44 int comp(const node & a ,const node & b) 45 {return a.w>b.w;} 46 47 int find(int x) 48 { 49 if(f[x]!=x) 50 f[x]=find(f[x]); 51 return f[x]; 52 } 53 void unionn(int x,int y) 54 { 55 int fx=find(x); 56 int fy=find(y); 57 f[fx]=fy; 58 } 59 void Biggest_Kruskal() 60 { 61 sort(edge+1,edge+num+1,comp); 62 int k=0; 63 for(int i=1;i<=num;i++) 64 { 65 int uu=edge[i].u; 66 int vv=edge[i].v; 67 if(find(uu)!=find(vv)) 68 { 69 a_add(i); 70 unionn(uu,vv); 71 k++; 72 } 73 if(k==n-1)break; 74 } 75 //for(int i=1;i<=anum;i++) 76 // cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].w<<" "<<a[i].next<<endl; 77 } 78 void Build_Tree(int p) 79 { 80 vis[p]=1; 81 for(int i=ahead[p];i!=-1;i=a[i].next) 82 { 83 int will=a[i].v; 84 if(vis[will])continue; 85 vis[will]=1; 86 87 deep[will]=deep[p]+1; 88 s[will][0]=p; 89 take[will][0]=a[i].w; 90 Build_Tree(will); 91 } 92 } 93 void Initialize_Step() 94 { 95 for(int i=1;i<=18;i++) 96 { 97 for(int j=1;j<=n;j++) 98 { 99 s[j][i]=s[s[j][i-1]][i-1];100 take[j][i]=min(take[j][i-1],take[s[j][i-1]][i-1]);101 }102 }103 }104 int LCA(int x,int y)105 {106 int ans=0x7ffffff;107 if(deep[x]<deep[y])108 swap(x,y);109 for(int i=18;i>=0;i--)110 {111 if(s[x][i]!=0)112 if(deep[s[x][i]]>=deep[y])113 {114 ans=min(ans,take[x][i]);115 x=s[x][i]; 116 }117 }118 if(x==y)119 return ans;120 for(int i=18;i>=0;i--)121 {122 if(s[x][i]!=s[y][i])123 {124 ans=min(ans,take[x][i]);125 ans=min(ans,take[y][i]);126 x=s[x][i];127 y=s[y][i];128 }129 }130 ans=min(ans,take[x][0]);131 ans=min(ans,take[y][0]);132 return ans;133 }134 int main()135 {136 // memset(take,0xf,sizeof(take));137 scanf("%d%d",&n,&m);138 139 for(int i=1;i<=n;i++)140 {head[i]=-1;f[i]=i;ahead[i]=-1;}141 142 for(int i=1;i<=m;i++)143 {144 scanf("%d%d%d",&x,&y,&z);145 edge_add(x,y,z);146 //edge_add(y,x,z);147 }148 Biggest_Kruskal();149 //deep[1]=1;150 for(int i=1;i<=n;i++)151 {152 if(vis[i]==0)153 Build_Tree(i);154 }155 156 Initialize_Step();157 int q;158 scanf("%d",&q);159 for(int i=1;i<=q;i++)160 {161 int x,y;162 scanf("%d%d",&x,&y);163 if(find(x)!=find(y))164 {165 printf("-1\n");166 continue;167 }168 printf("%d\n",LCA(x,y));169 }170 return 0;171 }