VIJOS-P1045 有些糊涂。 原来这才是真懂

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #define maxn 100010
 5 int u[maxn],v[maxn],r[maxn],p[maxn];
 6 double w[maxn];
 7 using namespace std;
 8 int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
 9 int cmp(const int i,const int j){return w[i]<w[j];}
10 double kruskal(int n,int count)
11 {
12   int k=n-1;
13   for(int i=0;i<n;i++) p[i]=i;//这地方换成p[i]=i结果就不一样了 我去去!!!
14   for(int i=0;i<count;i++) r[i]=i;//这地方换成r[i]为嘛结果就不一样了 我去
15   sort(r,r+count,cmp);
16   //for(int i=0;i<count;i++) printf("%d  ",r[i]);
17    double ans=0;
18   for(int i=0;i<count;i++)
19   {
20       int x,y;
21       int e=r[i];x=find(u[e]);y=find(v[e]);
22       if(x!=y)
23       {
24         ans+=w[e];
25         p[x]=y;
26         k--;
27       }
28    }
29    if(k!=0)  ans=100000000;//这地方应该是特别大的数
30     return ans;
31 }
32 int main()
33 {
34     double s;int n,count=0;
35     //freopen("input.txt","r",stdin);
36     scanf("%lf%d",&s,&n);
37     int a,b;double c;
38     while(scanf("%d%d%lf",&a,&b,&c)!=EOF)
39     {
40         u[count]=a-1;v[count]=b-1;w[count]=c;
41         count++;
42     }
43         /*for(int i=0;i<count;i++)
44          printf("%f  ",w[i]);*/
45 
46     double ans=kruskal(n,count);
47     if(count<n-1) { printf("Impossible\n"); return 0;}
48     if(ans<=s)
49         printf("Need %.2lf miles of cable\n",ans);
50     else printf("Impossible\n");
51     return 0;
52 }

来总结一下问题:

1.标号为1-N,这个算法是针对0-N-1的,上一个题对了,所以没发现这个问题

2.得结合题目要求去做。 k一开始=n-1,是使所有的点之间都能连接。  //这往下可以不用,自己前面一开始写错了,if(k!=0) ans=100000000;//这地方应该是特别大的数,而count<n-1则直接无法连通(是小于n-1,不是小于n)

3.另外OJ上虽然自己是照一组数据写的,但也可能是多组测试数据。望都全面应对!

4.相信OJ,否定自己@@

posted @ 2013-03-09 10:42  闭关修炼的小孩纸  阅读(290)  评论(0编辑  收藏  举报