hdu 畅通工程系列题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232
并查集水。
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; const int N = 1000; int n,m; int father[N]; int _find(int x){ if(x==father[x]) return x; return _find(father[x]); } int main(){ while(scanf("%d",&n)!=EOF,n){ for(int i=1;i<=n;i++){ father[i] = i; } scanf("%d",&m); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); int x = _find(a); int y = _find(b); father[x] = y; } int ans = 0; for(int i=1;i<=n;i++){ if(father[i]==i) ans++; } printf("%d\n",ans-1); } }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233
kruskal水
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; const int N = 105; int n,m; int father[N]; struct Edge{ int s,e,len; }edge[N*(N-1)/2]; int _find(int x){ if(x==father[x]) return x; return _find(father[x]); } int cmp(Edge a,Edge b){ return a.len<b.len; } int kruskal(int m){ sort(edge+1,edge+m+1,cmp); int cost = 0; for(int i=1;i<=m;i++){ int x = _find(edge[i].s); int y = _find(edge[i].e); if(x!=y){ father[x] = y; cost+=edge[i].len; } } return cost; } int main(){ while(scanf("%d",&n)!=EOF,n){ for(int i=1;i<=n;i++){ father[i] = i; } int m = n*(n-1)/2; for(int i=1;i<=m;i++){ scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].len); } printf("%d\n",kruskal(m)); } }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863
kruskal水+判断强连通分量
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; const int M = 105; const int N = M*(M-1)/2; struct Edge{ int s,e,len; }edge[N]; int father[M],n,m; int _find(int x){ if(x==father[x]) return x; return _find(father[x]); } int cmp(Edge a,Edge b){ return a.len<b.len; } int kruskal(int m){ sort(edge+1,edge+m+1,cmp); int cost = 0; for(int i=1;i<=m;i++){ int x = _find(edge[i].s); int y = _find(edge[i].e); if(x!=y){ father[x] = y; cost += edge[i].len; } } return cost; } int main(){ while(scanf("%d%d",&n,&m)!=EOF,n){ for(int i=1;i<=m;i++) father[i] = i; for(int i=1;i<=n;i++){ scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].len); } int cost = kruskal(n); int ans = 0; for(int i=1;i<=m;i++){ if(father[i]==i) ans++; } if(ans==1) printf("%d\n",cost); else printf("?\n"); } }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1875
将平面上的点都连接起来求最小生成树最后再判断一下强连通分量。
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; const int N = 105; const double eps = 1e-8; struct Point{ int x,y; }p[N]; struct Edge{ int s,e; double len; }edge[N*(N-1)/2]; int father[N]; int n; int _find(int x){ if(x==father[x]) return x; return _find(father[x]); } double dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } bool check(double k){ if(k+eps<10) return false; if(k-eps>1000) return false; return true; } int cmp(Edge a,Edge b){ return a.len<b.len; } double kruskal(int m){ sort(edge+1,edge+m+1,cmp); double cost = 0; for(int i=1;i<=m;i++){ int x = _find(edge[i].s); int y = _find(edge[i].e); if(x!=y){ father[x] = y; cost +=edge[i].len;; } } return cost; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++) father[i] = i; for(int i=0;i<n;i++){ scanf("%d%d",&p[i].x,&p[i].y); } int m =1; for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ double len = dis(p[i],p[j]); if(!check(len)) continue; edge[m].s = i; edge[m].e = j; edge[m++].len = dis(p[i],p[j]); } } m--; double cost = kruskal(m); int ans = 0; for(int i=0;i<n;i++){ if(father[i]==i) ans++; } if(ans==1) printf("%.1lf\n",cost*100); else printf("oh!\n"); } }
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1879
处理一下输入,kruskal水
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; const int N = 105; struct Edge{ int s,e,len; }edge[N*(N-1)/2]; int n,m; int father[N]; int _find(int x){ if(x==father[x]) return x; return _find(father[x]); } int cmp(Edge a,Edge b){ return a.len<b.len; } int kruskal(int m){ sort(edge+1,edge+m+1,cmp); int cost = 0; for(int i=1;i<=m;i++){ int x = _find(edge[i].s); int y = _find(edge[i].e); if(x!=y){ father[x] = y; cost+=edge[i].len; } } return cost; } int main(){ while(scanf("%d",&n)!=EOF,n){ for(int i=1;i<=n;i++) father[i] = i; int m = n*(n-1)/2; for(int i=1;i<=m;i++){ int c,d; scanf("%d%d%d%d",&edge[i].s,&edge[i].e,&c,&d); if(!d) edge[i].len=c; else edge[i].len =0; } printf("%d\n",kruskal(m)); } }