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,否定自己@@