原题
题目分析
第一眼可能看不出是最小生成树,但仔细想想其实题目所要求的就符合最小生成树的性质.因此只需要用prim算出最小生成树,在求的过程中记录最小生成树中边的最大值即可.
代码
1 #include <iostream> 2 #include <algorithm> 3 #include <utility> 4 #include <cstdio> 5 #include <cmath> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <map> 12 #include <set> 13 14 using namespace std; 15 typedef long long LL; 16 const int INF_INT=0x3f3f3f3f; 17 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 18 19 typedef pair<int,int> P; 20 int n,m; 21 int edge[3000][3000]; 22 int used[3000]; 23 int ans; 24 25 void prim() 26 { 27 priority_queue<P,vector<P>,greater<P> > que; 28 for(int i=1;i<=n;i++) 29 if(edge[1][i]!=INF_INT) que.push(P(edge[1][i],i)); 30 used[1]=true; 31 while(que.size()) 32 { 33 P p=que.top();que.pop(); 34 if(used[p.second]) continue; 35 used[p.second]=true; 36 ans=max(ans,p.first); 37 for(int i=1;i<=n;i++) 38 if(edge[p.second][i]!=INF_INT&&!used[i]) que.push(P(edge[p.second][i],i)); 39 } 40 } 41 42 int main() 43 { 44 // freopen("black.in","r",stdin); 45 // freopen("black.out","w",stdout); 46 cin>>n>>m; 47 for(int i=1;i<=n;i++) 48 for(int j=1;j<=n;j++) edge[i][j]=INF_INT; 49 for(int i=0;i<m;i++) 50 { 51 int a,b,c; 52 scanf("%d %d %d",&a,&b,&c); 53 edge[a][b]=min(edge[a][b],c); 54 edge[b][a]=min(edge[b][a],c); 55 } 56 prim(); 57 printf("%d\n",ans); 58 return 0; 59 }