题目
试题编号 | 201703-4 |
---|---|
试题名称 | 地铁修建 |
时间限制 | 1s |
内存限制 | 256MB |
问题描述 | |
输入输出 | |
用例规模 |
题目分析
我开始是想用dfs去做的,为什么这么想?~~脑子瓦特了!~~没算内存限制,超内存了只给了25分;
后来仔细想一下,这道题是要从1到n的所有路径中找到一条路径,这条路径的最大分段在这几条路径中是最小的。想到这里我们就知道了,还有题目给的一定有通路的条件,这就是从最小生成树找就可以了啊,实现的方法是并查集!
不用找到一整颗树,每次加入边的时候,判断1和n是否联通就好了,一旦加入某条边联通了那么马上输出这条边的权就可以了。
AC代码
#include <iostream>
#include <stdio.h>
#include <queue>
#include <cstring>
#define mem(a) memset(a,0,sizeof(a))
#define rep(i,a,n) for(int i=a;i<n;i++)
#define min(a,b) ((a)>(b)?(b):(a))
using namespace std;
struct node{
int x;
int y;
int z;
bool operator<(const node &b)const{
return z>b.z;
}
node(int a,int b,int c){
x=a;
y=b;
z=c;
}
};
int father[100001];
int rankk[100001];
void init(int n){
rep(i,0,n){
father[i]=i;
rankk[i]=0;
}
}
int find(int x){
if(x==father[x])return x;
return father[x]=find(father[x]);
}
bool same(int x,int y){
return find(x)==find(y);
}
void merge(int a,int b){
int x=find(a);
int y=find(b);
if(x==y)return;
else{
if(rankk[x]>rankk[y]){
father[y]=x;
}
else{
father[x]=y;
if(rankk[x]==rankk[y])
rankk[y]++;
}
}
}
int main(){
int n,m;
int a,b,c;
scanf("%d%d",&n,&m);
init(n+1);
priority_queue<node>q;
while(m--){
scanf("%d%d%d",&a,&b,&c);
q.push(node(a,b,c));
}
int ans;
while(!q.empty()){
node k=q.top();
q.pop();
if(!same(k.x,k.y)){
merge(k.x,k.y);
if(same(1,n)){
ans=k.z;
break;
}
}
}
printf("%d\n",ans);
return 0;
}