Trail Maintenance(LightOJ-1123)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011815404/article/details/89384164

Problem Description

Tigers in the Sunderbans wish to travel freely among the N fields (numbered from 1 to N), even though they are separated by trees. The tigers wish to maintain trails between pairs of fields so that they can travel from any field to any other field using the maintained trails. Tigers may travel along a maintained trail in either direction.

The tigers do not build trails. Instead, they maintain deer trails that they have discovered. On any week, they can choose to maintain any or all of the deer animal trails they know about. Always curious, the tigers discover one new deer trail at the beginning of each week. They must then decide the set of trails to maintain for that week so that they can travel from any field to any other field. Tigers can only use trails which they are currently maintaining.

The tigers always want to minimize the total length of trail they must maintain. The tigers can choose to maintain any subset of the deer trails they know about, regardless of which trails were maintained the previous week. Deer trails (even when maintained) are never straight. Two trails that connect the same two fields might have different lengths. While two trails might cross, tigers are so focused; they refuse to switch trails except when they are in a field. At the beginning of each week, the tigers will describe the deer trail they discovered. Your program must then output the minimum total length of trail the tigers must maintain that week so that they can travel from any field to any other field, if there is such a set of trails.

Input

Input starts with an integer T (≤ 25), denoting the number of test cases.

Each case starts with two integers N (1 ≤ N ≤ 200) and W. W is the number of weeks the program will cover (1 ≤ W ≤ 6000).

Each of the next W lines will contain three integers describing the trail the tigers found that week. The first two numbers denote the end points (filed numbers) and the third number denotes the length of the trail (1 to 10000). No trail has the same field as both of its end points.

Output

For each case, print the case number in a line. Then for every week, output a single line with the minimum total length of trail the tigers must maintain so that they can travel from any field to any other field. If no set of trails allows the tigers to travel from any field to any other field, output "-1".

Sample Input

1
4 6
1 2 10
1 3 8
3 2 3
1 4 3
1 3 6
2 1 2

Sample Output

-1
-1
-1
14
12
8

题意:给定包含 n 个点的空图,依次加入 m 条带权边,每次加入一条边,就输出当前图中最小生成树的权值,如果没有生成树,则输出-1

思路:增量最小生成树模板题

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 10000+5;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
using namespace std;
struct Node {
    int u,v;
    int val;
    bool operator<(const Node& rhs)const {
        return val<rhs.val;
    }
} edge[N];
int n,m,cnt;
int father[N];
int Find(int x) {
    if(father[x]==x)
        return x;
    return father[x]=Find(father[x]);
}
void Kruskal() {
    sort(edge,edge+cnt);

    int pos=-1;
    int res=0,mst=0;
    for(int i=0; i<cnt; i++) {
        int u=edge[i].u,v=edge[i].v;
        int x=Find(u),y=Find(v);
        if(x!=y) {
            father[x]=y;
            res++;
            mst+=edge[i].val;
        } else {
            pos=i;
            continue;
        }
    }
    if(pos!=-1) {
        edge[pos]=edge[cnt-1];
        cnt--;
    }
    if(res!=n-1)
        printf("-1\n");
    else
        printf("%d\n",mst);
}
int main() {
    int t;
    scanf("%d",&t);
    
    int Case=1;
    while(t--){
        scanf("%d%d",&n,&m);
        printf("Case %d:\n",Case++);

        cnt=0;
        for(int i=0; i<m; i++) {//添m次边
            scanf("%d%d%d",&edge[cnt].u,&edge[cnt].v,&edge[cnt].val);
            cnt++;
            for(int i=0; i<N; i++)
                father[i]=i;
            Kruskal();//每次添边跑一次Kruskal
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/89384164