POJ 2485 Highways

来源:互联网 发布:软件行业会计处理 编辑:程序博客网 时间:2024/06/01 09:40

题目大意:

        岛国Flatopia地市平坦,适合公路的建造,但是该国还没有完善的公路系统,因此交通很不方便,该国政府意识到该问题的严重性了,因此计划修建公路使得在该国城镇之间行驶可以不离开公路系统。

        现有多个测例(测例数体重会给出),每个测例中都会给出城镇数N(3 ≤ N ≤ 500),编号1-N,接着给出一个N×N的矩阵,表示每两个城镇之间可修建的公路的长度(任意一条公路都连接着两个城镇,并且公路是双向的,即正向和反向的长度相同),司机不能在公路上转向,只能到达一个城镇后才能转向,各公路的最大长度d的范围是1 ≤ d ≤ 65,536,现需要修建公路网,使任何两个城镇之间可达(直接或间接),对每个测例求最短公路网中的最长路径。

题目链接

注释代码:

/*                      * Problem ID : POJ 2485 Highways * Author     : Lirx.t.Una                      * Language   : G++          * Run Time   : 188 ms                      * Run Memory : 676 KB                     */   #pragma G++ optimize("O2")#include <stdlib.h>#include <stdio.h>//infinity//总路线的最大长度//INF ≥ (最大城镇数(500)- 1)× 单条路径最大长度(65536)#defineINF3276800//maximum number of villages//城镇的最大数量#defineMAXVILN501//maximum number of distinct highways//最大的公路数量//因为算路径数量的时候会有一半重复(因为所有路径都是双向的)//并且需要排除自己到自己的路径//MAXDISDWN = ( 500 × 500 - 500 ) ÷ 2#defineMAXDISDWN124750structNode {//路径结点intu;//u、v为路径的两个端点intv;intd;//distance between u and v };typedefstruct NodeArcNode;typedefstruct Node *Arc;typedefstruct Node **PtArc;ArcNodean[MAXDISDWN];//node of arc,存放路径信息Arcarc[MAXDISDWN];//an的指针,利用指针访问并排序省时intset[MAXVILN];//并查集集合intfind(int x) {if ( x == set[x] )return x;return set[x] = find( set[x] );}intfcmp(const void *a, const void *b) {return (*(PtArc)a)->d - (*(PtArc)b)->d;}intprim( int n, int e ) {//prim最小生成树//但是这里题中要求求的是最小生成树中的最大路径//n为点的总数,e为边的总数intu, v;inti;intcnt;//count,记录已经有多少边被纳入集合了for ( i = 1; i <= n; i++ )set[i] = i;qsort(arc, e, sizeof(Arc), &fcmp);//将路径按长度从小到大排序for ( cnt = 0, i = 0; i < e; i++ ) {u = find( arc[i]->u );v = find( arc[i]->v );if ( u == v )//若两端点在一个集合就检查下一条边continue;if ( ++cnt == n - 1 )//否则cnt自加,看是否到达最小生成树//所要求的n - 1条边return arc[i]->d;//达到要求直接返回set[u] = v;//否则就将两点合并,即将该边纳入集合中}return INF;//搜索完所有边也没有达到n - 1条边,因此无生成树}intmain() {intt;intn;intd;inte;inti, j;scanf("%d", &t);while ( t-- ) {scanf("%d", &n);for ( e = 0, i = 1; i <= n; i++ )for ( j = 1; j <= n; j++ ) {scanf("%d", &d);if ( i < j ) {//将反向路径和自己到自己的边忽略an[e].u = i;an[e].v = j;an[e].d= d;arc[e]= an + e;e++;}}printf("%d\n", prim( n, e ));}return 0;}

无注释代码:

#pragma G++ optimize("O2")#include <stdlib.h>#include <stdio.h>#defineINF3276800#defineMAXVILN501#defineMAXDISDWN124750structNode {intu;intv;intd;};typedefstruct NodeArcNode;typedefstruct Node *Arc;typedefstruct Node **PtArc;ArcNodean[MAXDISDWN];Arcarc[MAXDISDWN];intset[MAXVILN];intfind(int x) {if ( x == set[x] )return x;return set[x] = find( set[x] );}intfcmp(const void *a, const void *b) {return (*(PtArc)a)->d - (*(PtArc)b)->d;}intprim( int n, int e ) {intu, v;inti;intcnt;for ( i = 1; i <= n; i++ )set[i] = i;qsort(arc, e, sizeof(Arc), &fcmp);for ( cnt = 0, i = 0; i < e; i++ ) {u = find( arc[i]->u );v = find( arc[i]->v );if ( u == v )continue;if ( ++cnt == n - 1 )return arc[i]->d;set[u] = v;}return INF;}intmain() {intt;intn;intd;inte;inti, j;scanf("%d", &t);while ( t-- ) {scanf("%d", &n);for ( e = 0, i = 1; i <= n; i++ )for ( j = 1; j <= n; j++ ) {scanf("%d", &d);if ( i < j ) {an[e].u = i;an[e].v = j;an[e].d= d;arc[e]= an + e;e++;}}printf("%d\n", prim( n, e ));}return 0;}

单词解释:

highway:n, 公路,大路,国道

island:n, 岛屿

island nation:n, 岛国

flat:adj, 扁平的

switch:vt, 转换,换向

guarantee:vt, 保证,担保

0 0