标签:
2 2 10 10 20 20 3 1 1 2 2 1000 1000
1414.2 oh!
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1875
还是最小生成树,但是有点改变,理解题目是关键“2个小岛之间的距离不能小于10米,也不能大于1000米”
这句话的意思是小岛之间的原始距离。。。
/** "2个小岛之间的距离不能小于10米,也不能大于1000米" 不是任意2个小岛,只是有桥的相连两个小岛间的距离限制, 不用考虑全部连通后的任意两个小岛间的距离. 果然想太多了.... */ #include <iostream> #include <cmath> #include <cstdio> using namespace std; const int INF=0x3f3f3f3f; struct node { double x,y; } t[105]; double a[105][105]; double dis[105]; bool vis[105]; int n; void Prime() { for(int i=0; i<n; i++) { dis[i]=a[0][i]; vis[i]=false; } dis[0]=0; vis[0]=true; double ans=0; for(int i=1; i<n; i++) { int p=-1; double minn=INF; for(int j=0; j<n; j++) { if(!vis[j]&&dis[j]<minn) minn=dis[p=j]; } if(p==-1) { cout<<"oh!"<<endl; return; } vis[p]=true; ans+=minn; for(int j=0; j<n; j++) { if(!vis[j]&&dis[j]>a[p][j]) dis[j]=a[p][j]; } } printf("%.1lf\n",ans*100); } int main() { int T; cin>>T; while(T--) { cin>>n; for(int i=0; i<n; i++) { for(int j=0; j<n; j++) if(i==j) a[i][j]=0; else a[i][j]=INF; } for(int i=0; i<n; i++) { cin>>t[i].x>>t[i].y; } for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(i==j) a[i][j]=0; else { a[i][j]=sqrt((t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y)); if(a[i][j]<10||a[i][j]>1000)//此处注意 a[i][j]=INF; } } } Prime(); } return 0; }
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int INF=0x3f3f3f3f; int fa[105]; int n,m; struct point { double x,y; } t[105]; struct node { int s,e; double w; } a[5000+5]; int Find(int x) { if(fa[x]==x) return x; return fa[x]=Find(fa[x]); } bool cmp(node a,node b) { return a.w<b.w; } double Kruskal() { for(int i=0; i<n; i++) fa[i]=i; sort(a,a+m,cmp); double ans=0; int cnt=n-1; for(int i=0; i<m; i++) { int x=Find(a[i].s); int y=Find(a[i].e); if(x!=y) { ans+=a[i].w; fa[x]=y; } } return ans; } int main() { int T; cin>>T; while(T--) { cin>>n; for(int i=0; i<n; i++) { cin>>t[i].x>>t[i].y; } m=0; for(int i=0; i<n; i++) { for(int j=0; j<i; j++) { double d=sqrt((t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y)); if(d>=10&&d<=1000) { a[m].s=i; a[m].e=j; a[m++].w=d; } } } double ans=Kruskal(); int cnt=0; for(int i=0; i<n; i++) { if(fa[i]==i) cnt++; } if(cnt>1) cout<<"oh!"<<endl; else printf("%.1lf\n",ans*100); } return 0; }
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int INF=0x3f3f3f3f; int fa[105]; int n,m; struct point { double x,y; } t[105]; struct node { int s,e; double w; } a[5000+5]; int Find(int x) { if(fa[x]==x) return x; return fa[x]=Find(fa[x]); } bool cmp(node a,node b) { return a.w<b.w; } void Kruskal() { for(int i=0; i<n; i++) fa[i]=i; sort(a,a+m,cmp); double ans=0; int cnt=0; for(int i=0; i<m; i++) { int x=Find(a[i].s); int y=Find(a[i].e); if(x!=y) { ans+=a[i].w; fa[x]=y; cnt++; } if(cnt==n-1) { printf("%.1lf\n",ans*100); return; } } cout<<"oh!"<<endl; } int main() { int T; cin>>T; while(T--) { cin>>n; for(int i=0; i<n; i++) { cin>>t[i].x>>t[i].y; } m=0; for(int i=0; i<n; i++) { for(int j=0; j<i; j++) { double d=sqrt((t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y)); if(d>=10&&d<=1000) { a[m].s=i; a[m].e=j; a[m++].w=d; } } } Kruskal(); } return 0; }
HDU 1875 畅通工程再续【最小生成树,Prime算法+Kruskal算法】
标签:
原文地址:http://blog.csdn.net/hurmishine/article/details/52127678