HDU 1863 畅通工程【最小生成树】

来源:互联网 发布:数控铣床编程太阳图案 编辑:程序博客网 时间:2024/05/29 18:09

题目链接

题目意思

给你n条边和m个城镇,城镇编号为1~m。现在要你求连通所有城镇的最小花费。如果不能连通就输出“?”。

解题思路

其实这就是一个简单的最小生成树的问题。我们可以用kruskal来写。注意我们要判断能不能形成通路,加一个标记变量。判断能不能形成回路即可。

代码部分

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int MAX=15000;int n,m,i,sum,pre[MAX],cnt,flag;struct node{    int from;///边的起点    int over;///边的终点    int weight;///边的权值}Edge[MAX];bool cmp(node a,node b){    return a.weight<b.weight;}int Find(int x){    if(pre[x]==x)        return x;    return pre[x]=Find(pre[x]);}int mix(int x,int y){    x=Find(x);    y=Find(y);    if(x!=y)    {        pre[y]=x;        ++cnt;///边数累加        flag=1;///标记变量    }}int kruskal(){    sort(Edge,Edge+n,cmp);    for(i=0; i<=m; i++)        pre[i]=i;    cnt=sum=0;    for(i=0; i<n; i++)    {        flag=0;        if(Find(Edge[i].from)!=Find(Edge[i].over))        {            mix(Edge[i].from,Edge[i].over);        }        if(flag)            sum+=Edge[i].weight;    }    if(cnt==m-1)    {        printf("%d\n",sum);    }    else        printf("?\n");}int main(){    int a,b,c;    while(~scanf("%d%d",&n,&m))    {        if(n==0)            break;        for(i=0; i<n; i++)        {            scanf("%d%d%d",&a,&b,&c);            Edge[i].from=a;            Edge[i].over=b;            Edge[i].weight=c;        }        kruskal();    }    return 0;}
原创粉丝点击