POJ 1789--Truck History(最小生成树)
2014-08-04 11:55
495 查看
本题要求最小生成树,因为已经是最大团,建议采用prim算法。
Prim算法实质为贪心思想,每次我们只选择一个到已加入生成树集合的点距离最近的点即可,且每加入一个新点都要更新其他点的最短距离。
最朴素的做法,设置一个是否在生成树集合的bool数组以及一个标志点到生成树的最小距离的数组,每次加入新点,更新最小距离时,且可以直接找出下一个加入的点。
另一种做法:因为本题距离只在1到7之间,想用类似hash的思想,设置7个队列,把最小距离为i的点直接放进队列q[i]中,这样每次从1到7遍历队列,遇到第一个没在生成树的点就说明此点位下一个加入生成树中的点,但是因为当最小距离更新时,我们不能删除这个点在较大距离的队列中的元素,所以有很多冗余,效果不理想。
Prim:
Prim&Queue:
Prim算法实质为贪心思想,每次我们只选择一个到已加入生成树集合的点距离最近的点即可,且每加入一个新点都要更新其他点的最短距离。
最朴素的做法,设置一个是否在生成树集合的bool数组以及一个标志点到生成树的最小距离的数组,每次加入新点,更新最小距离时,且可以直接找出下一个加入的点。
另一种做法:因为本题距离只在1到7之间,想用类似hash的思想,设置7个队列,把最小距离为i的点直接放进队列q[i]中,这样每次从1到7遍历队列,遇到第一个没在生成树的点就说明此点位下一个加入生成树中的点,但是因为当最小距离更新时,我们不能删除这个点在较大距离的队列中的元素,所以有很多冗余,效果不理想。
Prim:
#include<cstdio> #include<cstring> #define maxN 2001 #define maxL 8 #define INF 0X7F7F7F7F int truckNum; char truckCode[maxN][maxL]; char typeDis(int x,int y) { char dis = 0; for(int i = 0;i < maxL-1;i++) { if(truckCode[x][i] != truckCode[y][i]) dis++; } return dis; } int search_Prim() { int i,j; char truckDis[maxN]; //保存卡车到已加入生成树中的卡车最小距离 char IsInTree[maxN]; int minTrucknextTruck; int tmpDis,sumDis,minDis; sumDis = 0; memset(IsInTree,0,sizeof(IsInTree)); memset(truckDis,0X7F,sizeof(truckDis)); nextTruck = 0; for(i = 1;i < truckNum;i++) { minTruck = nextTruck; IsInTree[minTruck] = true; minDis = INF; for(j = 1;j < truckNum;j++) { if(!IsInTree[j]) { tmpDis = typeDis(minTruck,j); if(truckDis[j] > tmpDis) //更新最小距离 truckDis[j] = tmpDis; if(truckDis[j] < minDis) //从不在生成树中的点选择下一个加入树中的点 { minDis = truckDis[j]; nextTruck = j; } } } sumDis += minDis; } printf("The highest possible quality is 1/%d.\n",sumDis); return 0; } int main() { while(scanf("%d",&truckNum)&&truckNum) { getchar(); for(int i = 0;i < truckNum;i++) gets(truckCode[i]); search_Prim(); } return 0; }
Prim&Queue:
#include<cstdio> #include<cstring> #define maxN 2001 #define maxL 8 #define INF 0X7F7F7F7F #define qSize 2000 int truckNum; char truckCode[maxN][maxL]; class queue_self { short q[qSize+1]; int qHead; int qTail; public: queue_self():qHead(0),qTail(0){} void enQueue(int x) { q[qTail] = x; if(qTail == qSize) qTail = 0; else qTail++; } short deQueue() { short x = q[qHead]; if(qHead == qTail) qHead = 0; else qHead++; return x; } bool empty() { if(qHead == qTail) return true; else return false; } }; char typeDis(int x,int y) { char dis = 0; for(int i = 0;i < maxL-1;i++) { if(truckCode[x][i] != truckCode[y][i]) dis++; } return dis; } int search_Prim() { int i,j; char truckDis[maxN]; char IsInTree[maxN]; int minTruck; int minDis,tmpDis,sumDis; char IsFindMin; queue_self q[maxL]; sumDis = 0; memset(IsInTree,0,sizeof(IsInTree)); memset(truckDis,0X7F,sizeof(truckDis)); truckDis[0] = 1; q[1].enQueue(0); for(i = 0;i < truckNum;i++) { IsFindMin = false; for(minDis = 1;minDis < maxL;minDis++) { while(!q[minDis].empty()) { j = q[minDis].deQueue(); if(!IsInTree[j]) { minTruck = j; IsFindMin = true; break; } } if(IsFindMin) break; } sumDis += minDis; IsInTree[minTruck] = true; for(j = 1;j < truckNum;j++) { if(!IsInTree[j]) { tmpDis = typeDis(minTruck,j); if(truckDis[j] > tmpDis) { truckDis[j] = tmpDis; q[tmpDis].enQueue(j); } } } } printf("The highest possible quality is 1/%d.\n",sumDis-1); return 0; } int main() { while(scanf("%d",&truckNum)&&truckNum) { getchar(); for(int i = 0;i < truckNum;i++) gets(truckCode[i]); search_Prim(); } return 0; }
相关文章推荐
- POJ1789 Truck History 最小生成树 + 路径压缩
- POJ 1789 Truck History 图论 prim算法 最小生成树
- POJ 1789-Truck History 最小生成树 Kruskal算法
- POJ-1789 Truck History 裸最小生成树
- 初级->图算法->最小生成树 poj 1789 Truck History
- poj 1789 Truck History 最小生成树
- POJ1789 Truck History(Prim最小生成树)
- poj 1789 Truck History 最小生成树
- poj1789 Truck History(最小生成树)
- poj1789 Truck History ——最小生成树入门题_Prim算法
- POJ1789 Truck History(最小生成树)
- POJ-1789 Truck History 最小生成树
- poj 1789 Truck History (最小生成树)
- POJ1789,Truck History,最小生成树,Prim
- POJ 1789 Truck History 最小生成树 KRUSKAL算法
- POJ 一 1789 Truck History(最小生成树)
- poj 1789 Truck History 最小生成树
- POJ 1789 Truck History【最小生成树简单应用】
- POJ1789--Truck History--最小生成树
- poj 1789 Truck History(最小生成树 prim)