Heavy Transportation (最大生成树的最小边)
思路:既然求最大生成树,那就把虽有的边的权重都变成负的,这样就能求得最大生成树了,然后来一个ans更新,每次比较边的大小就能找到最大边中的最小边了。
#include<stdio.h> #include<string.h> #include <iostream> #define MAX 0x3f3f3f3f using namespace std; int vis[2010]; int Map[2010][2010]; int dis[2010]; int n,m; int prim() { int i,j; int ans=MAX; for(i=1; i<=n; i++){ dis[i]=Map[1][i]; } dis[1]=0; vis[1]=1; int now=1; for(i=1; i<=n; i++){ int min1=0; for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]>min1) { now=j; min1=dis[j]; } } ans=min(ans,min1); if(now==n) //注意条件,如果说当前点now已经到达n说明已经找到一条路,就要跳出,否则可能导致ans再次更新,造成答案错误。 break; // cout<<"now "<<now<<" min1 "<<min1<<endl; vis[now]=1; for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]<Map[now][j]) dis[j]=Map[now][j]; } } return ans; } int main() { int t,cont=0; cin>>t; while(t--){ cont++; scanf("%d%d",&n,&m); for(int i=0;i<=n;i++) vis[i]=0; for(int i=0; i<=n; i++){ for(int j=0; j<=n; j++){ if(i==j) Map[i][j]=0; else Map[i][j]=-MAX; } } for(int i=0; i<m; i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(Map[x][y]<z) Map[x][y]=Map[y][x]=z; } int s=prim(); printf("Scenario #"); printf("%d:\n",cont); printf("%d\n\n",s); } return 0; }