POJ 3522 Slim Span【最大権利差最小生成樹Kruskyal】

6588 ワード

http://poj.org/problem?id=3522 Slim Span Time Limit:5000 MS Memory Limit:65536 K Total Submissions:9228 Acctepted:4905 Description
Given an undirected weightted graph G,you shou shoud find one of spanning trees specifid as follows.
The graph G is_orded pair(V,E),where V is a set of vertices{v 1,v 2,…,vn}and E is a set of undirected edges{e 1,e 2,…,em}.Each edge e haits weight(e)
A spanning tree T is a tree(a connected subgraphh without cycles)which connects all the n vertices with n−1 edges.The snes of a spanning tree T is defined as the difference between the largewest the
Figure 5:A grapph G and the weighs of the edges For example、a grapph G in Figure 5(a)has four vertices{v 1,v 2,v 3,v 4}and five undirected eedges{e 1,e 2,e 2,e 3,e 3,e 4,e 4,e 4,e 4,e 4,e 4,e 4,e 4,e 4,e 5,e 5,e 5,e 5,e 5,e 5,e 5,eeeeeeeeeeeeeeeeeeeedededededededededededededededededededededededededededeshown in Figure 5(b)
Figure 6:Examples of the spanning trees of G The e e e e e several spanning trees forG.Four of them are depicted in Figre 6(a)~(d)The spanning treeTain Figre 6(a)has threeeeeeeeeeeeeeeeeeeeedwhoeeeeeeeeeeeeeeeeedededededededededededededededededededededededededededededededededededededededeininininininininininininininininininininininininininininininininininis 4.The sleimness ses of spanning trees Tb、Tc and Td shown in Figure 6(b),(c)and(d)are 3,2 and 1,respanctively.You can see the sliness of any sther spanning tree is greater or equal to 1,thus the spanning tree Td Finess of the。
Your job is to write a program that computtes the slast sliness.
Input
The input consists of multile datasets,followed by a line containing two zros separated by a space.Each dataset has the following format.
n m a 1 b 1 b 1 w 1 m m m m m m m bm Every input item in a dataset isa non-negative integer.Items inininininininininininininininine e e e e e e e e separated bya space.n is the number of the vertices andm the m the nm the number the numbeber of the eeeeeeeeeeeeeeeeededededededededededededededededededededededededededededededededededededes.eeeeeeeeeeeeeeeeds.less than or equal to n、which represent the two vertices vak and vbk connected by the kth edge ek.wk is a positive integer less than or equal to 10000,which indicates the weight of ek.You can asume that the grapt=Vthere areのself-loops(that connect the same vertex)nor parallel edges(that are two or more edges whose both ends are the same two vertices)
Output
For each dataset,if the grapph has spanning trees,the smalest slaminess among the m shound be printed.Other wise,−1 shoud be printed.An out put shound not contain extra.
Sample Input
4 5 1 2 3 3 1 3 5 1 4 4 4 4 4 4 4 6 6 1 2 10 1 1 100 1 4 90 2 2 80 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 45 8 1 2 1 3 100 3 100 4 100 1 5 100 1 5 50 2 5 5 5 50 4 1 150 0 Sample Output
1 20-1-1 0 1686ソース
ジャパン2007
最大辺権差最小生成樹とは、1つの生成樹における最大辺と最小辺の差の値が、すべての生成樹の中で最小という意味である。
走査線でできるそうです。勉強したいです。実はタイトルの中の要求はkruskyalのやり方と同じです。kruskyalの優先的な選択は権利が最小で構築できる辺です。だから、私たちは権利区間の開始位置から末尾位置まで列挙して、複数のkruskyalの操作を行い、答えが一番小さい場合を取ることができます。もちろん、ある状態のツリーが作られないと、この状態はもちろん答えには含まれません。
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e4 + 10;
#define INF 0x7fffffff
struct edge { int u, v, w; }e[maxn];
int f[105];
int find(int i) {
    return f[i] == i ? i : f[i] = find(f[i]);
}
//bool operator
int cmp(edge a, edge b) { return a. w < b.w; }
int main()
{
    int n, m;
    while (~scanf("%d%d", &n, &m) && (n + m)) {
        for (int i = 0; i < m; i++) scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
        //sort(e, e + m);
        sort(e, e + m, cmp); int ans = INF;
        for (int i = 0; i < m; i++) {
            for (int j = 1; j <= n; j++) {
                f[j] = j;
            }
            int res = n;
            for (int j = i; j < m; j++) {
                if (find(e[j].u) != find(e[j].v)) {
                    res--; f[find(e[j].u)] = find(e[j].v);
                    if (res == 1) {
                        ans = min(ans, e[j].w - e[i].w);
                        //cout << 1 << endl;
                        break;
                    }
                }
            }
        }
        printf("%d
"
, ans == INF ? -1 : ans); } return 0; }