POJ 1797


提交了5次终于AC。参考了使用Dijkstra算法来求解之。

/*
 * poj_1797.c
 * accepted!
 */
#include <stdio.h>
#include <string.h> // memset ()
#include <limits.h> // INT_MAX
#define N (1010)
#define MY_MIN(a,b) ((a)<(b)?(a):(b))
#define SZL_DEBUG(fmt, args...) //printf("%d:"fmt"\n",__LINE__, ##args)
int pn_weight[N][N];
static int poj_1797 (int graph[N][N], int n, int m, int start, int end);

int main (){
    int n_scenarios, n_loop_scenarios;
    int n_vertices, n_edges;
    int n_result;
    //int pn_weight[N][N];
    int i,u,v,w;
    //freopen ("poj_1797_test_data.txt", "r", stdin);
    scanf ("%d", &n_scenarios);
    n_loop_scenarios = 1;
    while (n_loop_scenarios <= n_scenarios){
        memset (pn_weight, 0xFF, sizeof (int) * N * N); // assign -1 to array.
        scanf ("%d%d", &n_vertices, &n_edges);
        for (i=0; i<n_edges; i++){
           scanf ("%d%d%d", &u, &v, &w);
           pn_weight[u-1][v-1] = w;
           pn_weight[v-1][u-1] = w;
        }
        n_result = poj_1797 (pn_weight, n_vertices, n_edges, 0, n_vertices-1);
        printf ("Scenario #%d:\n%d\n\n", n_loop_scenarios, n_result);
        n_loop_scenarios ++;
    }
    //fclose (stdin);
    return 0;
}

static int poj_1797 (int graph[N][N], int n, int m, int start, int end){
    int pn_mweight[N];
    int pn_bweight[N];
    int pn_in_set[N];
    int n_is_set_full;
    int i,u,v,n_max,n_nextv;
    memset (pn_in_set, 0, sizeof (int) * N); /* assign 0 to set. */
    for (i=0; i<N; i++){
        pn_bweight[i] = 1; /* 1 indicates max weight is MAX. */
        pn_mweight[i] = INT_MAX;
    }
    u = start;
    n_is_set_full = 0;
    while (!n_is_set_full && u!=end){
        pn_in_set[u] = 1; /* put the start node to set S, VerticesSet=S(union)T, EmptySet = S(join)T. */
        for (v=0; v<n; v++){ /* using 'n' (not N) can also be okay. */
            if (graph[u][v] != -1 && !pn_in_set[v]){
                n_nextv = MY_MIN(graph[u][v],pn_mweight[u]);
                if (pn_bweight[v]){
                    pn_mweight[v] = n_nextv;
                    pn_bweight[v] = 0;
                }
                else {
                    if (n_nextv > pn_mweight[v]) {
                        pn_mweight[v] = n_nextv;
                    }
                }
            }
        }
        /* select from set T one node renaming to 'u' with the largest maxweight. */
        n_max = -1;
        n_is_set_full = 1;
        for (i=0; i<n; i++){ /* n vs N? */
            if (!pn_in_set[i] && !pn_bweight[i] && n_max<pn_mweight[i]){
                n_max = pn_mweight[i];
                u = i;
            }
            if (!pn_in_set[i]){
                n_is_set_full = 0;
            }
        }
    }
    if (0 != end-u){
        pn_mweight[u] = -1; 
    }
    return pn_mweight[u];
}

其中遇到的Bugs:
Bug1: 二维数组 pn_weight 的定义如果放到 main 函数中,那么会出现运行时错误, 报 Segmentation fault! 这估计是声明太多的空间,超过了操作系统分配给进程栈区空间容量大小从而引发的错误。怎样解决呢?我的方案是将该变量定义放到全局区,不占用栈区的空间。另外想到的方法是修改栈区的空间容量大小,应该如何去修改呢?

Bug2: 在使用 scanf 时,多输入了一个换行符 scanf ("%d%d\n", &a, &b),这会导致需要多输入一个回车符来确保程序执行,即需要输入连续的两个回车符号。正常情况不需要将它作为输入,而只是输入数据的间隔符号,所以在 scanf 中不需要显示指出换行符来。

Bug3: 逻辑错误:应该更新的情况弄反了,事实上,当节点 v 所关联的最大可以通过的重量是可比较的(已经更新过)那么在后续的更新过程中,仅当指向它的节点 u 关联的值和边 (u,v) 关联的值中的较小者大于 v 关联的值 并且 节点 v 不在集合 S 中时,才更新节点 v 的值为那个新的较小值(它大于节点 v 所关联的值)。

输入:

1
5 6
1 2 3
1 4 3
2 3 2
2 4 2
3 4 6
3 5 4

输出:

Scenario #1:
3


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值