今天做题找了一道最小生成树的题,是以前做过的类型,虽然不难,不过有点忘了,磨磨唧唧的做了好久才想起来...万幸最后想起来了,二分+最小生成树
题目大意:N个点之间有M条路,要求 N个点连通,选的路尽量少的前提下,求最长边的最小值
思路:一开始看到脑子里乱乱的,就记得路径肯定要N-1条、二分一开始都没想起来。。。只是感到熟悉,就试着敲敲,慢慢的边做边改,好不容易想起来的,题是不难,就是忘记了。。。各个知识点有点串。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define Max(a,b) (a>b?a:b)
#define MAXN 200005
#include<queue>
using namespace std;
int N,M,look[305],dp[305],mapp[305][305];
int dfs(int maxx)
{
int z=0,s=0,x=1,pp;
dp[1]=0;
while(1)
{
z=-1;
pp=maxx;
for(int i=1;i<=N;i++)
{
if((look[i]==0)&&(dp[i]<=pp))
{ z=i;pp=dp[i];}
}
if(z==-1) break;
look[z]=1;
x=z;
s++;
for(int i=1;i<=N;i++)
{
if(dp[i]>mapp[i][z]) dp[i]=mapp[i][z];
}
}
if(s==N) return 1;
else return 0;
}
int main()
{
int a,b,c,k,r;
while(~scanf("%d%d",&N,&M))
{memset(mapp,0x3f3f3f3f,sizeof(mapp));
r=0;
while(M--)
{
scanf("%d%d%d",&a,&b,&c);
mapp[a][b]=c;
mapp[b][a]=c;
if(c>r) r=c;
}
mapp[1][1]=0;
int l=0,mid=0;
while(1)
{
memset(look,0,sizeof(look));
memset(dp,0x3f3f3f3f,sizeof(dp));
if(mid==(l+r)/2) break;
mid=(l+r)/2;
if(dfs(mid)) r=mid;
else l=mid;
//cout<<l<<" "<<r<<"!! "<<mid<<endl;
}
printf("%d %d\n",N-1,r);
}
}