POJ1789-Truck History-最小生成树两种做法(Kruskal+Prim)模板题
就是题意不会太好理解和转换
最小生成树模板题
Kruskal:
1 //kruskal 2 #include<stdio.h> 3 #include<string.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<map> 9 #include<cmath> 10 using namespace std; 11 #define inf 0x3f3f3f3f 12 #define inff 0x3f3f3f3f3f3f3f3f 13 const int N=2200; 14 #define mod 998244353 15 typedef long long ll; 16 17 int f[N]; 18 char a[N][10]; 19 20 struct node 21 { 22 int l,r,d; 23 } e[N*N]; 24 25 int getf(int x) 26 { 27 if(f[x]==x) 28 return x; 29 return f[x]=getf(f[x]); 30 } 31 32 int merge(int x,int y) 33 { 34 int t1=getf(x); 35 int t2=getf(y); 36 if(t1!=t2) 37 { 38 f[t2]=t1; 39 return 1; 40 } 41 return 0; 42 } 43 44 bool cmp1(node x,node y) 45 { 46 return x.d<y.d; 47 } 48 int main() 49 { 50 ios::sync_with_stdio(false); 51 int n; 52 while(cin>>n) 53 { 54 if(n==0) 55 break; 56 memset(e,0,sizeof(e)); 57 /*for(int i=1;i<=n;i++) 58 { 59 for(int j=1;j<=n;j++) 60 { 61 if(i==j) 62 e[i][j]=0; 63 else 64 e[i][j]=inf; 65 } 66 }*/ 67 for(int i=1; i<=n; i++) 68 { 69 scanf("%s",a[i]); 70 f[i]=i; 71 } 72 int p=0; 73 for(int i=1; i<=n; i++) 74 { 75 for(int j=1; j<=n; j++) 76 //for(int j=i+1; j<=n; j++) 77 { 78 int sum=0; 79 for(int k=0; k<7; k++) 80 { 81 if(a[i][k]!=a[j][k]) 82 sum++; 83 } 84 //e[i][j]=e[j][i]=sum; 85 e[p].l=i; 86 e[p].r=j; 87 e[p++].d=sum; 88 } 89 } 90 int w,ans=0; 91 sort(e,e+p,cmp1); 92 for(int i=0; i<p; i++) 93 { 94 if(merge(e[i].l,e[i].r)==1) 95 { 96 w++; 97 ans+=e[i].d; 98 } 99 if(w==n-1) 100 break; 101 } 102 cout<<"The highest possible quality is 1/"<<ans<<"."<<endl; 103 } 104 return 0; 105 }
Prim:
1 //prim 2 #include<stdio.h> 3 #include<string.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<map> 9 #include<cmath> 10 using namespace std; 11 #define inf 0x3f3f3f3f 12 #define inff 0x3f3f3f3f3f3f3f3f 13 const int N=2200; 14 #define mod 998244353 15 typedef long long ll; 16 17 int e[N][N],dist[N]; 18 int n,ans; 19 bool book[N]; 20 char a[N][10]; 21 22 void prim() 23 { 24 int countt=1;//countt代表点数,而不是边数 25 ans=0;//记录路径长度 26 for(int i=1;i<=n;i++) 27 { 28 dist[i]=e[1][i]; 29 book[i]=0; 30 } 31 book[1]=1; 32 while(countt<n) 33 { 34 int minn=inf,u; 35 for(int i=1;i<=n;i++) 36 { 37 if(!book[i]&&dist[i]<minn) 38 { 39 minn=dist[i]; 40 u=i; 41 } 42 } 43 ans+=minn; 44 countt++; 45 book[u]=1; 46 for(int i=1;i<=n;i++) 47 { 48 if(!book[i]&&dist[i]>e[u][i]) 49 { 50 dist[i]=e[u][i]; 51 } 52 } 53 } 54 55 } 56 int main() 57 { 58 ios::sync_with_stdio(false); 59 while(cin>>n) 60 { 61 if(n==0) 62 break; 63 for(int i=1;i<=n;i++) 64 { 65 for(int j=1;j<=n;j++) 66 { 67 if(i==j) 68 e[i][j]=0; 69 else 70 e[i][j]=inf; 71 } 72 } 73 for(int i=1; i<=n; i++) 74 scanf("%s",a[i]); 75 for(int i=1; i<=n; i++) 76 { 77 for(int j=1; j<=n; j++) 78 //for(int j=i+1; j<=n; j++) 79 { 80 int sum=0; 81 for(int k=0; k<7; k++) 82 { 83 if(a[i][k]!=a[j][k]) 84 sum++; 85 } 86 e[i][j]=e[j][i]=sum; 87 } 88 } 89 prim(); 90 cout<<"The highest possible quality is 1/"<<ans<<"."<<endl; 91 } 92 return 0; 93 }