畅通工程系列问题题解(HDU 1233 1863 1875 1879)

来源:互联网 发布:怎么申请网站域名 编辑:程序博客网 时间:2024/05/29 19:59

HDU 1233

krusal

#include <iostream>#include <cstring>#include <algorithm>using namespace std;#define maxnum 5051int n,line;//sum为最小权之和,n为顶点个数,line为边数int cnt;int par[maxnum];double sum;struct node{int u,v;double w;}list[maxnum];int cmp(node a,node b){return a.w < b.w;}int find(int x)//并查集的路径压缩{if(par[x] == -1)return x;return par[x] = find(par[x]);}void kruskal(){int i,j;sort(list,list+line,cmp);for(i=0,sum=0;i<line;i++){int x = find(list[i].u);int y = find(list[i].v);if(x != y){sum += list[i].w;cnt++;par[x] = y;}if(cnt == n-1)break;}}int main(){int i,j;int vis;double len;int t;while(scanf("%d",&n),n){memset(par,-1,sizeof(par));line = n*(n-1)/2;for(i=0;i<line;i++){scanf("%d%d%lf",&list[i].u,&list[i].v,&list[i].w);}cnt=0;kruskal();    cout<<sum<<endl;}return 0;}

HDU  1863

krusal

#include <iostream>#include <queue>#include <map>#include <cstring>#include <algorithm>using namespace std;#define maxnum 105int sum,n,line;//sum为最小权之和,n为顶点个数,line为边数int u[maxnum],v[maxnum],w[maxnum],r[maxnum],p[maxnum];//u起点,v终点,w权值int cmp(const int i,const int j){return w[i] < w[j];}int find(int x)//并查集的路径压缩{return p[x]==x?x:p[x]=find(p[x]);}int kruskal(){int i,j,k;int cnt = 0;for(i=0;i<line;i++)r[i] = i;for(i=0;i<n;i++)p[i] = i;sort(r,r+line,cmp);for(i=0,sum=0;i<line;i++){int x = find(u[r[i]]);int y = find(v[r[i]]);if(x != y){sum += w[r[i]];cnt++;p[x] = y;}}if(cnt != n-1)sum = 0;return sum;}int main(){int i,j,k;int len;int t,s,d,p,q;while(cin>>line>>n,line){for(i=0;i<line;i++){cin>>u[i]>>v[i]>>w[i];}t = kruskal();if(t)cout<<t<<endl;else    cout<<"?"<<endl;}return 0;}

hdu 1875

代码一  krusal  100+ms

#include <iostream>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int n;//sum为最小权之和,n为顶点个数,line为边数int cnt;int par[101];double sum;struct node{int u;int v;double w;}list[6000];struct node2{double u,v;}list2[101];int cmp(node a,node b){return a.w < b.w;}int find(int x)//并查集的路径压缩{if(par[x] == -1)return x;return par[x] = find(par[x]);}double kruskal(int line){int i,j;sort(list,list+line,cmp);for(i=0,sum=0;i<line;i++){int x = find(list[i].u);int y = find(list[i].v);if(x != y){sum += list[i].w;cnt++;par[x] = y;}if(cnt == n-1)return sum;}return 0;}int main(){int i,j,N,k,kk;int vis,line;int len;int p,q;double bian,t;scanf("%d",&N);while(N--){scanf("%d",&n);memset(par,-1,sizeof(par));for(i=0,k=0;i<n;i++){scanf("%lf%lf",&list2[i].u,&list2[i].v);for(j=0;j<i;j++){bian = sqrt(pow(fabs(list2[j].u-list2[i].u),2.0)+fabs(pow(list2[j].v-list2[i].v,2.0)));if(bian >= 10 && bian <= 1000){list[k].u = j+1;list[k].v = i+1;list[k++].w = bian;}}}cnt = 0;t = kruskal(k);if(t)  printf("%.1lf\n",t*100);else  cout<<"oh!"<<endl;}return 0;}
代码二Prim  优先队列  60+ms   

#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;int n;//sum为最小权之和,n为顶点个数,line为边数int cnt;int par[101];int link[101][101];double c[101][101];int yiwei[101];int vis[6001];double sum;struct node{int u;int v;double w;};struct node2{double u,v;}list2[101];bool operator < (const node &a,const node &b){return a.w > b.w;}int prim(int s){int i,j,k,m,t,u,total;memset(vis,0,sizeof(vis));priority_queue <node> qq;struct node nn;total  = 1;vis[s] = 1;sum = 0;while(total < n){for(i=1;i<link[s][0];i++){if(!vis[link[s][i]]){nn.u = s;nn.v = link[s][i];nn.w = c[s][nn.v];qq.push(nn);}}while(!qq.empty() && vis[qq.top().v])//遇到顶点和集合外的顶点没有相连的qq.pop();//刚巧这个点作为终点是最短的,因为这个顶点没背标记过,所以会错误的计入在内if(qq.empty())break;nn = qq.top();s = nn.v;sum += nn.w;vis[s] = 1;//标记为集合内的元素qq.pop();total++;}if(total == n)return 1;elsereturn 0;}int main(){int i,j,N,k,kk;int vis,line;int len;int p,q;double bian,t;scanf("%d",&N);while(N--){scanf("%d",&n);memset(par,-1,sizeof(par));for(i=1,k=0;i<=n;i++){link[i][0] = 1; scanf("%lf%lf",&list2[i].u,&list2[i].v);for(j=1;j<i;j++){bian = sqrt(pow(fabs(list2[j].u-list2[i].u),2.0)+fabs(pow(list2[j].v-list2[i].v,2.0)));if(bian >= 10 && bian <= 1000){c[j][i] = c[i][j] = bian;link[i][link[i][0]++] = j;link[j][link[j][0]++] = i;}}}cnt = 0;kk = prim(1);if(kk)  printf("%.1lf\n",sum*100);else  cout<<"oh!"<<endl;}return 0;}

HDU  1879

krusal+并查集

#include <iostream>#include <cstring>#include <algorithm>using namespace std;#define maxnum 5051int n;//sum为最小权之和,n为顶点个数,line为边数int cnt;int par[maxnum];int sum;struct node{int u,v;double w;}list[maxnum];struct node2{int u,w;}list2[maxnum];int cmp(node a,node b){return a.w < b.w;}int find(int x)//并查集的路径压缩{if(par[x] == -1)return x;return par[x] = find(par[x]);}int kruskal(int line){int i,j;sort(list,list+line,cmp);for(i=0,sum=0;i<line;i++){int x = find(list[i].u);int y = find(list[i].v);if(x != y){sum += list[i].w;cnt++;par[x] = y;}if(cnt == n-1)return sum;}return 0;}int fun(int kk){int i;for(i=0;i<kk;i++){int x = find(list2[i].u);int y = find(list2[i].w);if(x != y){cnt++;par[x] = y;}if(cnt == n-1)return 1;}return 0;}int main(){int i,j,k,kk;int vis,line;int len;int t,p,tt,q;while(scanf("%d",&n),n){k = kk = 0;memset(par,-1,sizeof(par));line = n*(n-1)/2;for(i=0;i<line;i++){scanf("%d%d%d%d",&p,&q,&len,&vis);if(vis){list2[kk].u = p;list2[kk++].w = q;}else{list[k].u = p;list[k].v = q;list[k++].w = len;}}cnt=t=tt=0;if(kk)  tt = fun(kk);if(tt)cout<<"0"<<endl;elsecout<<kruskal(k)<<endl;}return 0;}



0 0
原创粉丝点击