POJ 2075 Tangled in Cables 最小生成树

简单的最小生成树,不过中间却弄了很久,究其原因,主要是第一次做生成树,很多细节不够熟练,find()函数的循环for判断条件是 pre[i]>=0,也就是遇到pre[i]==-1时停止,i就是并查集的代表元、

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #define MAXN 1000
  6 #define MAXE 1000010
  7 #define LEN 25
  8 #define esp 1e-9
  9 
 10 char name[MAXN][LEN];
 11 int n,m;
 12 
 13 typedef struct
 14 {
 15     int u,v;
 16     double w;
 17 } EDGE;
 18 
 19 int dblcmp(double x)
 20 {
 21     if(fabs(x)<esp)
 22         return 0;
 23     return x>0?1:-1;
 24 }
 25 
 26 int cmp(const void*i,const void*j)
 27 {
 28     EDGE *a=(EDGE*)i;
 29     EDGE *b=(EDGE*)j;
 30     return dblcmp(a->w-b->w);
 31 }
 32 
 33 EDGE edge[MAXE];
 34 int pre[MAXN];
 35 
 36 int find(int x)
 37 {
 38     int i=x;
 39     for(; pre[i]>=0; i=pre[i])  ;
 40     while(i!=x)
 41     {
 42         int t=pre[x];
 43         pre[x]=i;
 44         x=t;
 45     }
 46     return i;
 47 }
 48 
 49 void link(int x,int y)
 50 {
 51     if(pre[x]>pre[y])
 52     {
 53         pre[x]+=pre[y];
 54         pre[y]=x;
 55     }
 56     else
 57     {
 58         pre[y]+=pre[x];
 59         pre[x]=y;
 60     }
 61 }
 62 int p;/*记录edge数目的变量不要和输入数据的变量混用*/
 63 void add_EDGE(int u,int v,double w)
 64 {
 65     edge[p].u=u;
 66     edge[p].v=v;
 67     edge[p].w=w;
 68     p++;/*记得更新*/
 69 }
 70 
 71 int match(char *s)
 72 {
 73     int i;
 74     for(i=0;i<n;i++)
 75         if(strcmp(name[i],s)==0)
 76         break;
 77         return i;
 78 }
 79 
 80 double tot;
 81 void input(void)
 82 {
 83     int i;
 84     char s1[LEN],s2[LEN];
 85     double w;
 86     scanf("%lf%d",&tot,&n);
 87     for(i=0; i<n; i++)
 88         scanf("%s",name[i]);
 89     int u,v;
 90     scanf("%d",&m);
 91     for(i=0; i<m; i++)
 92     {
 93         scanf("%s%s%lf",s1,s2,&w);
 94         u=match(s1);
 95         v=match(s2);
 96         add_EDGE(u,v,w);
 97     }
 98 }
 99 
100 double k(void)
101 {
102     int i,num=0;
103     double ans=0.0;
104     qsort(edge,p,sizeof(EDGE),cmp);
105    /* for(i=0;i<p;i++)
106         printf("%d %d %f\n",edge[i].u,edge[i].v,edge[i].w); */
107     for(i=0;i<p;i++)
108     {
109         int u=edge[i].u;
110         int v=edge[i].v;
111         int x,y;
112         if((x=find(u))!=(y=find(v)))
113            {
114                ans+=edge[i].w;
115                num++;
116                link(x,y);
117            }
118            if(num==n-1)
119             break;
120     }
121     return ans;
122 }
123 
124 void solve(void)
125 {
126     memset(pre,-1,sizeof(pre));
127    double mst=k();
128    /*printf("%lf\n",mst);*/
129    if(mst>tot)
130     puts("Not enough cable");
131    else printf("Need %.1f miles of cable\n",mst);
132 }
133 
134 int main(void)
135 {
136     input();
137     solve();
138     return 0;
139 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值