ZOJ 3204 Connect them(最小生成树之Krusal 输出字典序最小的)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367

You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is
the same as connecting computers j and i). The cost of connecting computer i and computer j is cij. You cannot connect some pairs of computers due to some particular reasons. You want to connect them
so that every computer connects to any other one directly or indirectly and you also want to pay as little as possible.

Given n and each cij , find the cheapest way to connect computers.

Input

There are multiple test cases. The first line of input contains an integer T (T <= 100), indicating the number of test cases. Then T test cases follow.

The first line of each test case contains an integer n (1 < n <= 100). Then n lines follow, each of which contains n integers separated by a space.
The j-th integer of thei-th line in these n lines is cij, indicating the cost of connecting computers i and j (cij = 0 means that you cannot connect them). 0 <= cij <=
60000, cij = cjicii = 0, 1 <= i,j <= n.

Output

For each test case, if you can connect the computers together, output the method in in the following fomat:

i1 j1 i1 j1 ......

where ik ik (k >= 1) are the identification numbers of the two computers to be connected. All the integers must be separated by a space and there must be
no extra space at the end of the line. If there are multiple solutions, output the lexicographically smallest one (see hints for the definition of "lexicography small") If you cannot connect them, just output "-1" in the line.

Sample Input

2
3
0 2 3
2 0 5
3 5 0
2
0 0
0 0

Sample Output

1 2 1 3
-1

Hints:

A solution A is a line of p integers: a1a2, ...ap.

Another solution B different from A is a line of q integers: b1b2, ...bq.

A is lexicographically smaller than B if and only if:

(1) there exists a positive integer r (r <= pr <= q) such that ai = bi for all 0 < i < r and ar < br

OR

(2) p < q and ai = bi for all 0 < i <= p


Author: CAO, Peng

Source: The 6th Zhejiang Provincial Collegiate Programming Contest

题意:

输出最小生成树中字典序最小的!

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 147
int F[maxn];
struct Edge
{
    int u, v;
    int w;
} edge[maxn*maxn], ans[maxn*maxn];
int n;
int tol;
int cnt;
void addedge(int u,int v,int w)
{
    edge[tol].u = u;
    edge[tol].v = v;
    edge[tol].w = w;
    tol++;
}
bool cmp1(Edge a,Edge b)//保证按字典序从小输出
{
    if(a.w != b.w)
        return a.w < b.w;
    else if(a.u != b.u)
        return a.u < b.u;
    else
        return a.v < b.v;
}
bool cmp2(Edge a,Edge b)
{
    if(a.u != b.u)
        return a.u < b.u;
    else
        return a.v < b.v;
}
int find(int x)
{
    return x == F[x] ? x: F[x]=find(F[x]);
}
void kruscal()
{
    for(int i = 0; i <= n; i++)
    {
        F[i] = i;
    }
    sort(edge,edge+tol,cmp1);//对边的排序
    cnt = 0;
    for(int i = 0; i < tol; i++)
    {
        int u = edge[i].u;
        int v = edge[i].v;
        int t1 = find(u);
        int t2 = find(v);
        if(t1 != t2)
        {
            ans[cnt++] = edge[i];
            F[t1] = t2;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        tol = 0;
        int w;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                scanf("%d",&w);
                if(j <= i)continue;
                if(w == 0)continue;
                addedge(i,j,w);
            }

        kruscal();
        if(cnt!=n-1)
        {
            printf("-1\n");
        }
        else
        {
            sort(ans,ans+cnt,cmp2);
            for(int i = 0; i < cnt-1; i++)
                printf("%d %d ",ans[i].u,ans[i].v);
            printf("%d %d\n",ans[cnt-1].u,ans[cnt-1].v);
        }
    }
    return 0;
}

时间: 2024-12-04 22:10:20

ZOJ 3204 Connect them(最小生成树之Krusal 输出字典序最小的)的相关文章

ZOJ 3204 Connect them (C) 最小生成树kruskal

Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is the sa

HDU 1848 2SAT 输出字典序最小

告诉你两两冲突的序列,让输出字典序最小. 一开始老老实实tarjan,写完了发现后面完全不能好弄,因为选了第一个点,你没办法快速找出全部对立组,只能找出本来在一个pair中的那个对立组,而找不出给定的那个随意的对立组.所以直接从1开始染色,弄不出来就染2.以此类推. 这个题还有一个教训就是,点要多开一倍,边也要多开一倍.老是忘... #include<algorithm> #include<iostream> #include<cstdio> #include<c

ZOJ 3204 Connect them(最小生成树:kruscal算法)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3204 Connect them Time Limit: 1 Second     Memory Limit:32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN).All connecti

zoj 3204 Connect them(最小生成树)

题意:裸最小生成树,主要是要按照字典序. 思路:模板 prim: #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define INF 0x7fffffff #define MAXN 128 bool vis[MAXN]; int lowu[MAXN];//记录起始边(已加入集合中的边) int lowc[MAX

ZOJ 3204 Connect them(最小生成树+最小字典序)

Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers iand j is the sam

POJ 1861 &amp;amp; ZOJ 1542 Network(最小生成树之Krusal)

题目链接: PKU:http://poj.org/problem?id=1861 ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=542 Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the c

POJ 1861 &amp; ZOJ 1542 Network(最小生成树之Krusal)

题目链接: PKU:http://poj.org/problem?id=1861 ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=542 Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the c

ZOJ 3204 Connect them MST-Kruscal

这道题目麻烦在输出的时候需要按照字典序输出,不过写了 Compare 函数还是比较简单的 因为是裸的 Kruscal ,所以就直接上代码了- Source Code : //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring

ZOJ 3204: Connect Them

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 #include <iostream> #include <algorithm> #include <limits> #include <queue> using namespace std; const int MAXN = 105, INF = numeric_limits<int>::max(); typedef