题目描述 <small>Description</small>

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

输入描述 <small>Input Description</small>

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

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

输出描述 <small>Output Description</small>

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

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

样例输入 <small>Sample Input</small>

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

样例输出 <small>Sample Output</small>

2

1 4

2 5

17

数据范围及提示 <small>Data Size & Hint</small>

n<=100

毕竟是模板,所以必须要保存下。

至于题解,看程序就可以懂啦O(∩_∩)O哈哈~

//Asimple
//#include <bits/stdc++.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cstdlib>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <limits.h>
#include <time.h>
#define INF 0xfffffff
#define mod 999101
#define PI 3.14159265358979323
#define swap(a,b,t) t = a, a = b, b = t
#define CLS(a, v) memset(a, v, sizeof(a))
#define debug(a)  cout << #a << " = "  << a <<endl
#define dobug(a, b)  cout << #a << " = "  << a << " " << #b << " = " << b << endl
#define srd(a) scanf("%d", &a)
#define src(a) scanf("%c", &a)
#define srs(a) scanf("%s", a)
#define srdd(a,b) scanf("%d %d",&a, &b)
#define srddd(a,b,c) scanf("%d %d %d",&a, &b, &c)
#define prd(a) printf("%d\n", a)
#define prdd(a,b) printf("%d %d\n",a, b)
#define prs(a) printf("%s\n", a)
#define prc(a) printf("%c", a)
using namespace std;
inline int abs(int x){return x<0?-x:x;}
typedef long long ll;
const int maxn = 105;
int n, m, num, T, k, len, ans, sum, x, y;
int Map[maxn][maxn];
bool vis[maxn];int arr[maxn][2];
void solve() {
    int Min, sum = 0;
    int adv[maxn];
    int lowc[maxn];
    CLS(vis, false);
    
    for(int i=2; i<=n; i++) lowc[i] = INF;
    lowc[1] = 0;
    
    for(int l=1; l<=n; l++) {
        Min = INF;
        int index = 0;
        for(int j=1; j<=n; j++) {
            if( !vis[j] && lowc[j]<Min ) {
                Min = lowc[j];
                index = j;
            }
        }
        sum += Map[adv[index]][index];
        vis[index] = true;
        for(int i=2; i<=n; i++) {
            if( !vis[i] && Map[index][i]<lowc[i]) {
                lowc[i] = Map[index][i];
                adv[i] = index;
            }
        }
        if( Min ) {
            arr[len][0] = min(adv[index], index);
            arr[len][1] = max(adv[index], index);
            len++;
        }
    }
    cout << len << endl;
    for(int i=0; i<len; i++) {
        cout << arr[i][0] << " " << arr[i][1] << endl;
    }
    cout << sum << endl;
}

void input() {
    srd(n);
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=n; j++) {
            srd(Map[i][j]);
        }
    }
    solve();
}

int main(){
    input();
    return 0;
}