• CODE[VS] 1003 电话连线


    题目描述 Description

    一个国家有n个城市。若干个城市之间有电话线连接,现在要增加m条电话线(电话线当然是双向的了),使得任意两个城市之间都直接或间接经过其他城市有电话线连接,你的程序应该能够找出最小费用及其一种连接方案。

    输入描述 Input Description

        输入文件的第一行是n的值(n<=100).

        第二行至第n+1行是一个n*n的矩阵,第i行第j列的数如果为0表示城市i与城市j有电话线连接,否则为这两个城市之间的连接费用(范围不超过10000)。

    输出描述 Output Description

           输出文件的第一行为你连接的电话线总数m,第二行至第m+1行为你连接的每条电话线,格式为i j,(i<j), i j是电话线连接的两个城市。输出请按照Prim算法发现每一条边的顺序输出,起始点为1.

           第m+2行是连接这些电话线的总费用。

    样例输入 Sample Input

    5

    0 15 27 6 0

    15 0 33 19 11

    27 33 0 0 17

    6 19 0 0 9

    0 11 17 9 0

    样例输出 Sample Output

    2

    1 4

    2 5

    17

    数据范围及提示 Data Size & Hint

    n<=100


    这个题是非常标准的Prim最小生成树的问题。他的输出顺序可以先用一个二维下标为2的数组存储,最后结束的时候打印出来即可。

    直接上代码

    /*************************************************************************
        > File Name: 电话连线.c
        > Author: zhanghaoran
        > Mail: 467908670@qq.com 
        > Created Time: 2015年05月25日 星期一 10时03分14秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <string.h>
    
    #define INF 100000
    int Prim(int a[][100], int n){
    	int low[100];
    	int b[100][2];
    	int used[100];
    	int closeset[100];
    	int i, j, k, min;
    	int flag = 0;
    	int icount = 0;
    	int count = 0;
    	int t = 0;
    	for(i = 0; i < n ; i ++){
    		low[i] = a[0][i];
    		used[i] = 0;
    		closeset[i] = 0;
    	}
    	used[i] = 0;
    	for(i = 0; i < n - 1; i++){
    		j = 0;
    		min = INF;
    		for(k = 1; k < n; k ++)
    			if(!used[k] && low[k] < min){
     	 			j = k;
    				min = low[k];
    				if(min == 0){
    	   				flag = 1;
    					break;
    				}
    			}
    		used[j] = 1;
    		count += min;
    		if(flag == 0){
    			icount ++;
    			b[t][0] = j + 1 < closeset[j] + 1 ? j + 1 : closeset[j] + 1;
    			b[t][1] = j + 1 > closeset[j] + 1 ? j + 1 : closeset[j] + 1;    //用来存储最后输出的数据
    			t ++;
    		}
    		flag = 0;                      //如果中间连通的话那么就不将其存储
    		for(k = 1; k < n; k ++)
    			if(!used[k] && a[j][k] < low[k]){
    	  			low[k] = a[j][k];
    	 			closeset[k] = j;
    		}
    	}
    	printf("%d
    ", icount);
    	for(i = 0; i < icount; i++){
    		printf("%d %d
    ", b[i][0], b[i][1]);
    	}
    	return count;
    }
    
    int main(void){
    	int n;
    	int a[100][100];
    	int i, j;
    	scanf("%d", &n);
    	for(i = 0; i < n; i ++){
    		for(j = 0; j < n; j ++){
    			scanf("%d", &a[i][j]);
    		}
    	} 
    	printf("%d
    ", Prim(a, n));
    }


  • 相关阅读:
    【leetcode】1030. Matrix Cells in Distance Order
    【leetcode】1031. Maximum Sum of Two Non-Overlapping Subarrays
    【leetcode】1032. Stream of Characters
    L120 单词造句
    L119
    L118
    2018.8.6邮件规范一
    L117
    L116
    L115
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136141.html
Copyright © 2020-2023  润新知