看完题意,这里要注意理解我们的目的是求出在所有 能从起点到终点的每一条路径中拥挤度的最大值中得到一个最小值,例如上面的样例就是从1到3存在两条路径,一条路径中的拥挤度最大值为3,一条为2,因此输出2
第一感觉该题可以使用最短路径的dijkstra解决,我们将原本dijkstra中的dis[i]数组的含义改为从起点到i点的最大拥挤度,然后因为会遍历到不同的路径,因此我们在遍历的过程中更新dis数组,即对应上面的在最大值中找最小值
#include<iostream> #include<vector> #include<queue> #include<algorithm> #define pii pair<int,int> #define ll long long using namespace std; const int MAX=2e4+10,inf=0x3f3f3f3f; int n,m,s,t; typedef struct Node{ int to,w; }Node; vector<Node>groupA[MAX];//邻接表存储图 int dis[MAX]; int visited[MAX]; void dijkstra1(int s){ for(int i=0;i<MAX;i++)dis[i]=inf,visited[i]=false; dis[s]=0; priority_queue<pii,vector<pii>,greater<pii> >q; q.push({0,s}); while(!q.empty()){ int u=q.top().second; q.pop(); if(visited[u]){ continue; } visited[u]=true; int len=groupA[u].size(); for(int i=0;i<len;i++){ int v=groupA[u][i].to,cost=max(dis[u],groupA[u][i].w);//这里改为求路径上拥挤度较大值 if(dis[v]>cost){//求在所有max中求较小值 dis[v]=cost; q.push({dis[v],v}); } } } } int main(){ ll ans=0; cin>>n>>m>>s>>t; for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; groupA[u].push_back(Node{v,w}); groupA[v].push_back(Node{u,w});//无向 } dijkstra1(s); cout<<dis[t]<<endl; return 0; }
第二思路是想使用最小生成树算法克鲁斯卡尔解决,因为克鲁斯卡尔每次都会选择权值最小的边来构图,如果在某一个时刻,我们加入了一条边导致了起点s和终点t相连了,而此时因为我们所选择的边都是排好序的了,那么我们此时选到的边一定是相对来说的较小值了
#include<bits/stdc++.h> using namespace std; const int MAX=2e4+10; int n,m,s,t; struct Node{ int u,v,w; }arr[MAX]; int parent[MAX]; bool cmp(Node node1,Node node2){ return node1.w<node2.w;//按权值排序 } int find(int c){ if(parent[c]==c){ return c; }else{ return parent[c]=find(parent[c]); } } int main(){ cin>>n>>m>>s>>t; for(int i=1;i<=m;i++)parent[i]=i;//初始化 for(int i=1;i<=m;i++){ cin>>arr[i].u>>arr[i].v>>arr[i].w; } sort(arr+1,arr+m+1,cmp); for(int i=1;i<=m;i++){ int a=find(arr[i].u),b=find(arr[i].v); // cout<<arr[i].w<<endl; if(a!=b){ parent[a]=parent[b]; } if(find(s)==find(t)){ cout<<arr[i].w<<endl; break; } } return 0; }