LAN 문제를 푸는 중입니다.
테스트 케이스 다 맞고, 제가 추가로 만든 예제에서도 결과가 잘 나오는데
제출하니 오답이라고 뜨네요.
조언 부탁드립니다.
방법은
모든 node 사이 edge들의 weight를 구한뒤
이미 있는 edge의 weight를 0으로 만들고
최소 스패닝 트리 알고리즘을 썼습니다.
#include <stdio.h>#include <math.h>typedefstructEdge{intn1;intn2;doubledist;}EDGE;EDGEedge[124750];intX[500],Y[500];intC,N,M;EDGEtmp[124750];intc=0;intcycle[500]={0,};doublesum=0.0;intnum_edges=0;voidmerge(intleft,intmid,intright){intl=left;intr=mid+1;intidx=0;while(l<=mid&&r<=right){if(edge[l].dist<edge[r].dist)tmp[idx++]=edge[l++];elsetmp[idx++]=edge[r++];}while(l<=mid)tmp[idx++]=edge[l++];while(r<=right)tmp[idx++]=edge[r++];for(inti=left;i<=right;i++)edge[i]=tmp[i-left];}voidmerge_sort(intleft,intright){if(left<right){intmid=(left+right)/2;merge_sort(left,mid);merge_sort(mid+1,right);merge(left,mid,right);}}voidconnect(intn1,intn2,doubledist){//NO Cycleif(cycle[n1]==0&&cycle[n2]==0){c++;cycle[n1]=c;cycle[n2]=c;sum+=dist;num_edges++;}elseif(cycle[n1]!=0&&cycle[n2]==0){cycle[n2]=cycle[n1];sum+=dist;num_edges++;}elseif(cycle[n1]==0&&cycle[n2]!=0){cycle[n1]=cycle[n2];sum+=dist;num_edges++;}elseif(cycle[n1]!=0&&cycle[n2]!=0&&cycle[n1]!=cycle[n2]){for(intj=0;j<N;j++){if(cycle[j]==cycle[n2])cycle[j]=cycle[n1];}sum+=dist;num_edges++;}//else -> Cycle!}intmain(){inti;inta,b;inttotal_edges;scanf("%d",&C);while(C--){scanf("%d %d",&N,&M);for(i=0;i<N;i++)scanf("%d",&X[i]);for(i=0;i<N;i++)scanf("%d",&Y[i]);// 모든 node 간의 edge dist 구하기total_edges=0;for(i=0;i<N;i++){for(intj=i+1;j<N;j++){edge[total_edges].n1=i;edge[total_edges].n2=j;edge[total_edges].dist=sqrt(pow((double)(X[i]-X[j]),2)+pow((double)(Y[i]-Y[j]),2));total_edges++;}}//이미 edge가 존재하면, 그 edge는 dist를 0으로 -> MST 만들때 가장 처음에 추가하기 위해for(i=0;i<M;i++){scanf("%d %d",&a,&b);for(intj=0;j<total_edges;j++){if((edge[j].n1==a&&edge[j].n2==b)||(edge[j].n1==b&&edge[j].n2==a)){edge[j].dist=0;//연결connect(edge[j].n1,edge[j].n2,edge[j].dist);break;}}}merge_sort(0,total_edges-1);for(i=0;i<total_edges;i++){//연결connect(edge[i].n1,edge[i].n2,edge[i].dist);if(num_edges==N-1)break;}printf("%.10lf\n",sum);c=0;for(i=0;i<N;i++)cycle[i]=0;sum=0.0;num_edges=0;}return0;}
이부분에서 cycle[n2]가 먼저 업데이트 될 경우 문제가 발생합니다ㅠㅠ cycle[n2]를 임시변수에 저장해두고 업데이트하니 정답이 뜨는군요. 이런 data structure를 union find 혹은 disjoint-set이라고 하고, 여기에 잘 짜여진 알고리즘이 있습니다.
freestar
LAN 문제를 푸는 중입니다.
테스트 케이스 다 맞고, 제가 추가로 만든 예제에서도 결과가 잘 나오는데
제출하니 오답이라고 뜨네요.
조언 부탁드립니다.
방법은
모든 node 사이 edge들의 weight를 구한뒤
이미 있는 edge의 weight를 0으로 만들고
최소 스패닝 트리 알고리즘을 썼습니다.
9년 전