复习kruskal算法,外带字符串的二分,qsort的使用,并查集的基本应用。 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #define N 200 using namespace std; struct edge { int a,b; double dist; }e[N*N]; char h[N][25]; int set[N]; int cmp(const void *a,const void *b) { edge *p1=(edge *)a; edge *p2=(edge *)b; if(p1->dist >= p2->dist) return 1; else return -1; } int namecmp(const void *a,const void *b) { return strcmp((char *)a,(char *)b); } int binsearch(char sou[][25],char *key,int n) { int left=1,right=n,mid; while(left<=right) { mid=(left+right)/2; if(!strcmp(sou[mid],key)) return mid; else if(strcmp(sou[mid],key)>0) right=mid-1; else left=mid+1; } } int find(int x) { int r=x,j; while(r!=set[r]) r=set[r]; int i=x; while(i!=r) { j=set[i]; set[i]=r; i=j; } return r; } void merge(int a,int b) { if(a>b) set[a]=b; else set[b]=a; } double kruskal(int n,int m) { int i,a,b; double dist=0; for(i=1;i<=n;i++) set[i]=i; for(i=1;i<=m;i++) { a=find(e[i].a); b=find(e[i].b); if(a!=b) { dist+=e[i].dist; merge(a,b); } } return dist; } int main() { int n,m,i,a,b; double d,t,j; char s1[25],s2[25]; scanf("%lf%d",&t,&n); for(i=1;i<=n;i++) scanf("%s",h[i]); qsort(h+1,n,sizeof(h[1]),namecmp); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%s%s%lf",s1,s2,&d); a=binsearch(h,s1,n); b=binsearch(h,s2,n); e[i].a=a,e[i].b=b,e[i].dist=d; } qsort(e+1,m,sizeof(e[1]),cmp); j=kruskal(n,m); if(t>=j) printf("Need %.1lf miles of cable/n",j); else printf("Not enough cable/n"); return 0; } 用prim写的: #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<queue> #define N 300 using namespace std; #define inf 100000000.0 struct Gragh { int v; double dist; Gragh* next; }; Gragh *g[N]; struct node { int v; double dist; }; struct cmp { bool operator()(node a,node b) { return a.dist>b.dist; } }; priority_queue<node,vector<node>,cmp>que; char h[N][25]; bool use[N]; double dist[N]; int namecmp(const void *a,const void *b) { return strcmp((char *)a,(char *)b); } int binsearch(char sou[][25],char *key,int n) { int left=1,right=n,mid; while(left<=right) { mid=(left+right)/2; if(!strcmp(sou[mid],key)) return mid; else if(strcmp(sou[mid],key)>0) right=mid-1; else left=mid+1; } } void add_edge(int u,int v,double d) { Gragh *ptr=new Gragh; ptr->v=v; ptr->dist=d; ptr->next=g[u]; g[u]=ptr; return ; } double prim(int s,int n) { node temp,add; double d=0; int i; for(i=1;i<=n;i++) dist[i]=inf; memset(use,0,sizeof(use)); dist[s]=0; temp.dist=0; temp.v=s; while(!que.empty()) que.pop(); que.push(temp); while(!que.empty()) { temp=que.top(); que.pop(); if(use[temp.v]) continue; use[temp.v]=1; d+=temp.dist; for(Gragh *ptr=g[temp.v];ptr;ptr=ptr->next) { if(use[ptr->v]) continue; if(dist[ptr->v]>ptr->dist) { dist[ptr->v]=ptr->dist; add.dist=dist[ptr->v]; add.v=ptr->v; que.push(add); } } } return d; } int main() { int n,m,i,a,b; double d,t,j; char s1[25],s2[25]; scanf("%lf%d",&t,&n); for(i=1;i<=n;i++) scanf("%s",h[i]); qsort(h+1,n,sizeof(h[1]),namecmp); scanf("%d",&m); for(i=1;i<=n;i++) g[i]=NULL; for(i=1;i<=m;i++) { scanf("%s%s%lf",s1,s2,&d); a=binsearch(h,s1,n); b=binsearch(h,s2,n); add_edge(a,b,d); add_edge(b,a,d); } j=prim(1,n); if(t>=j) printf("Need %.1lf miles of cable/n",j); else printf("Not enough cable/n"); return 0; }