您的位置:首页 > 其它

UVALive 3887 边权极差最小生成树模板

2018-02-02 21:08 411 查看
距期末考还剩两天  GG

这类题要枚举图上的最小边 然后求最小生成树

想一下,最小边之后剩下的边要有n-1-1条 图才能连通 所以下标从1开始的时候枚举到m-n-2就行 取等、

vjudge传送门

要注意一些变量每次循环要初始化

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=201;
const int maxm=20001;
struct edge{
int u,v,w;
}e[maxm<<1];
//枚举最小边 求最小生成树
int n,m,fa[maxn],eid=0;
int get(int x){return fa[x]==x?x:fa[x]=get(fa[x]);}
void merge(int a,int b){
a=get(a),b=get(b);
if(a!=b) {fa[a]=b;}
}
bool cmp(edge a,edge b){return a.w<b.w;}
inline int read(){
int s=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
s=s*10+c-48;
c=getchar();
}
return s*f;
}
int res=99999999;
void init(){
for(int i=1;i<=n;i++) fa[i]=i;
//maxw=-1;
}
int main(){

while(scanf("%d%d",&n,&m)==2&&n){
int a,b,c;
eid=0,res=99999999;

for(int i=1;i<=m;i++)
{
a=read();b=read();c=read();
e[++eid].u=a;e[eid].v=b;e[eid].w=c;
}
sort(e+1,e+m+1,cmp);
// bool flag=true;
for(int k=1;k<=m-n+2;k++)//枚举最小边 求最小生成树
{
init();
int rst=n;
for(int i=k;i<=m;i++) //不必重复排序
{

int x=e[i].u;int y=e[i].v;
if(get(x)!=get(y)){
merge(x,y);
rst--;
}
//printf("%d %d\n",rst,res);
if(rst==1){ //n-1条边 图连通
res=min(e[i].w-e[k].w,res);
break;
}
}
}
if(res!=99999999) printf("%d\n",res);
else printf("-1\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: