图论——最小生成树
2015-02-21 17:01
344 查看
poj 3723(Kruskal)
从给出的数据可以看出,其不一定是树,更可能是森林,并且根据题意是要求边的总和最大化。故相对的挑选Kruskal算法,而不是prim,只需将权值改为负数即可等效为求最小生成树。
同时注意,所给的示例中我们得注意到,他有可能给同样的girl和boy不同的数值,如第二组测试数据中既有 “2 4 9820”,又有“2 4 8326”,这时我们要挑最大的那个值作为边的权值存储。
代码比较耗时,还有可以改进的地方。仅供参考!
poj 1789(prim)
题意:
数据中给出的每行字符串代表一种货车,货车可由其他货车“衍生”,现在问:在最佳“衍生”关系的条件下,求“ the highest possible quality of a derivation plan. ”,即“衍生”关系中父子的字符串中不同的字母的个数和。
以测试数据为例:
如上图所示,当2,3,4都被1“衍生”出来时便是最佳“衍生”关系,此时的 the highest possible quality of a derivation plan. ”就等于1/3。
代码如下:
如有错误,还望指出!
转载请注明出处:http://blog.csdn.net/big_heart_c
从给出的数据可以看出,其不一定是树,更可能是森林,并且根据题意是要求边的总和最大化。故相对的挑选Kruskal算法,而不是prim,只需将权值改为负数即可等效为求最小生成树。
同时注意,所给的示例中我们得注意到,他有可能给同样的girl和boy不同的数值,如第二组测试数据中既有 “2 4 9820”,又有“2 4 8326”,这时我们要挑最大的那个值作为边的权值存储。
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<algorithm> using namespace std; #define MAX 50050 int father[MAX], son[MAX]; int v, l; typedef struct Kruskal { //存储边的信息 int a; int b; int value; }; bool cmp(const Kruskal & a, const Kruskal & b) { return a.value < b.value; } int unionsearch(int x) { //查找根结点+路径压缩 return x == father[x] ? x : unionsearch(father[x]); } bool join(int x, int y) { //合并 int root1, root2; root1 = unionsearch(x); root2 = unionsearch(y); if(root1 == root2) //为环 return false; else if(son[root1] >= son[root2]) { father[root2] = root1; son[root1] += son[root2]; } else { father[root1] = root2; son[root2] += son[root1]; } return true; } int main() { int ncase, ltotal, sum, flag,boy , girl; Kruskal edge[MAX]; scanf("%d", &ncase);//原先用cin超时了 //cin>>ncase; while(ncase--) { scanf("%d%d%d", &girl, &boy, &l); //cin>>girl>>boy>>l; v = girl + boy; ltotal = 0, sum = 0, flag = 0; for(int i = 0; i <= v; ++i) { //初始化 father[i] = i; son[i] = 1; } for(int i = 1; i <= l ; ++i) {//初始化 edge[i].value = 0; } for(int i = 1; i <= l ; ++i) { int A,B,V; //cin>>A>>B>>V; scanf("%d%d%d", &A, &A, &V); if(V > -edge[i].value) {//使所输入的边权值最大 edge[i].a = A; edge[i].b = B+girl; edge[i].value = -V; } } sort(edge + 1, edge + 1 + l, cmp); //按权值由小到大排序 for(int i = 1; i <= l; ++i) { if(join(edge[i].a, edge[i].b)) { ltotal++; //边数加1 sum += edge[i].value; //记录权值之和 //cout<<edge[i].a<<"->"<<edge[i].b<<" = "<<edge[i].value<<endl; } } printf("%d\n", sum+10000*v); } return 0; }
代码比较耗时,还有可以改进的地方。仅供参考!
poj 1789(prim)
题意:
数据中给出的每行字符串代表一种货车,货车可由其他货车“衍生”,现在问:在最佳“衍生”关系的条件下,求“ the highest possible quality of a derivation plan. ”,即“衍生”关系中父子的字符串中不同的字母的个数和。
以测试数据为例:
如上图所示,当2,3,4都被1“衍生”出来时便是最佳“衍生”关系,此时的 the highest possible quality of a derivation plan. ”就等于1/3。
代码如下:
#include<iostream> #include<string.h> #include<fstream> using namespace std; #define Max_N 2002 char truck[Max_N][8]; int dis[Max_N][Max_N] = {0}; int N; #define inf 0x3f3f3f3f bool vis[Max_N]; int lowc[Max_N]; void find_dis() {//找出各顶点间的关系 for(int i = 0; i<N; i++) { for(int j=i; j<N; j++) { int temp_num = 0; if(i == j) { dis[i][j] = 7; continue; } for(int k =0; k<7; k++) { if(truck[i][k] != truck[j][k]) { temp_num++; } } dis[i][j] = temp_num; dis[j][i] = temp_num; } } } int prim() { int i, j, p; int minc, res = 0; memset(vis, 0, sizeof(vis)); vis[0] = 1; for (i=1; i<N; i++) lowc[i] = dis[0][i]; for (i=1; i<N; i++) { minc = inf; p = -1; for (j=0; j<N; j++) if (0 == vis[j] && minc > lowc[j]) { minc = lowc[j]; p = j; } if (inf == minc) return -1; // 原图不连通 res += minc; vis[p] = 1; for (j=0; j<N; j++) if (0 == vis[j] && lowc[j] > dis[p][j]) lowc[j] = dis[p][j]; } return res; } int main() { //ifstream in("C://a.txt",std::ios::in); memset(truck,NULL,sizeof(truck)); while(cin>>N , N!= 0) { cin.getline(truck[0],8); for(int i=0; i<N; i++) { cin.getline(truck[i],8); } find_dis(); cout<<"The highest possible quality is 1/"<<prim()<<"."<<endl; } }
如有错误,还望指出!
转载请注明出处:http://blog.csdn.net/big_heart_c
相关文章推荐
- (复习)图论--最小生成树--Kruskal算法
- |Tyvj|图论最小生成树|P1831 繁忙的都市
- 图论总结(8)最小生成树
- 图论(五)------最小生成树
- POJ 2377 Bad Cowtractors [图论.最小生成树] 《挑战程序设计竞赛》2.5
- 图论-Prim最小生成树
- hdu4786-图论训练3-最小生成树
- (精)(图论加强)布线问题(最小生成树)
- HPU图论专项(graph)【拓扑--二分图--最小生成树---树的直径---并查集--奇偶树---最小环---强联通】
- hdu 1102 Constructing Roads(图论:最小生成树)
- 图论-最小生成树(MST)算法
- 图论(九)最小生成树-Kruskal算法
- 【最小生成树】图论复习(三)
- 图结构练习——最小生成树 分类: 最小生成树 图论 2015-06-09 17:00 13人阅读 评论(0) 收藏
- ssl1615-Frogger【图论,最小生成树,并查集】
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 图论 邻接链表存储 BFS DFS 拓扑排序 最小生成树 KRUSKAL PRIM
- POJ2560-雀斑(Freckles)【图论,并查集,最小生成树,KURUSKAL】
- 图论--最小生成树总结(Prim&&Kruskal)
- 「图论」最小生成树-Prime算法