Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem F:
There is No Alternative

ICPC (Isles of Coral Park City) consist of several beautiful islands.

The citizens requested construction of bridges between islands to resolve inconveniences of using boats between islands, and they demand that all the islands should be reachable from any other islands via one or more bridges.

The city mayor selected a number of pairs of islands, and ordered a building company to estimate the costs to build bridges between the pairs. With this estimate, the mayor has to decide the set of bridges to build, minimizing the total construction cost.

However, it is difficult for him to select the most cost-efficient set of bridges among those connecting all the islands. For example, three sets of bridges connect all the islands for the Sample Input 1. The bridges in each set are expressed by bold edges in Figure F.1.

Figure F.1. Three sets of bridges connecting all the islands for Sample Input 1

As the first step, he decided to build only those bridges which are contained in all the sets of bridges to connect all the islands and minimize the cost. We refer to such bridges as no alternative bridges. In Figure F.2, no alternative bridges are drawn as thick edges for the Sample Input 1, 2 and 3.

Figure F.2. No alternative bridges for Sample Input 1, 2 and 3

Write a program that advises the mayor which bridges are no alternative bridges for the given input.

Input

The input consists of a single test case.

$N$ $M$

$S_1$ $D_1$ $C_1$

.

.

.

$S_M$ $D_M$ $C_M$

The first line contains two positive integers $N$ and $M$. $N$ represents the number of islands and each island is identified by an integer 1 through $N$. $M$ represents the number of the pairs of islands between which a bridge may be built.

Each line of the next $M$ lines contains three integers $S_i$, $D_i$ and $C_i$ ($1 \leq i \leq M$) which represent that it will cost $C_i$ to build the bridge between islands $S_i$ and $D_i$. You may assume $3 \leq N \leq 500$, $N − 1 \leq M \leq min(50000, N(N − 1)/2)$, $1 \leq S_i < D_i \leq N$, and $1 \leq C_i \leq 10000$. No two bridges connect the same pair of two islands, that is, if $i \ne j$ and $S_i = S_j$, then $D_i \ne D_j$ . If all the candidate bridges are built, all the islands are reachable from any other islands via one or more bridges.

Output

Output two integers, which mean the number of no alternative bridges and the sum of their construction cost, separated by a space.

Sample Input 1

4 4
1 2 3
1 3 3
2 3 3
2 4 3

Sample Output 1

1 3

Sample Input 2

4 4
1 2 3
1 3 5
2 3 3
2 4 3

Sample Output 2

3 9

Sample Input 3

4 4
1 2 3
1 3 1
2 3 3
2 4 3

Sample Output 3

2 4

Sample Input 4

3 3
1 2 1
2 3 1
1 3 1

Sample Output 4

0 0

Solution in C (judge verdict: Accepted)

/* aoj1350  */
//提出用
#include<stdio.h>
#include <stdlib.h>  // qsort
#define N 500  //島の数の最大
#define M 50000 //橋の数の最大

int mst[M]={0};  //最初に作った最小木の橋を記憶する
int flag=0;      //最小木が1度作られたかどうか
int rm = -1;   //取り除いた橋の番号(初期値-1)

//橋を定義
typedef struct bridge{  
    //始点の島,終点の島,コスト
    int s; int d; int c;
}bridge_t;

//比較関数(qsort用)
int cmp(const void *a,const void *b){
  return ((bridge_t*)a)->c - ((bridge_t*)b)->c;
}

//与えられた要素の木の根を再帰で求める関数
int u_root(int x,int number[]){
    //根
    if(number[x-1] == x)
        return x;

    //経路圧縮
    else
        return number[x-1] = u_root(number[x-1],number);
}

//xとyが同じ集合に属するか否かを根を見て判断する(同じなら1を返す)
int u_find(int x, int y, int number[]){
    return u_root(x,number) == u_root(y,number);
}

//xとyの属する集合を併合
void u_union(int x, int y, int number[]){     //x,yは島の番号(1~)を表す
    number[y-1] = x;
}

//全ての要素が同じ集合に含まれているかどうかをfindで判定する関数
int allsame(int n, int number[])
{
    int y;
    for(y=2;y<=n;y++)
            if(!u_find(1,y,number)) //一つでも同じ集合に含まれない要素があるなら0を返す
                return 0;
    return 1; //全ての要素が同じ集合に含まれていれば1を返す。
}


//クラスカル法で最小全域木を生成する関数
//異常終了(最小木が生成できなかった)の時は0を返す
int kruskal(bridge_t b[], int n, int m, int number[]){
    int i=0; //配列の添字
    int mc=0;  //最小木のコスト
    //独立した点がなくなるまで繰り返す
    while(!allsame(n,number)){
        //独立していてかつ取り除かれた橋でないならその要素の根を合成する
        if(!u_find(b[i].s,b[i].d,number) && i!=rm){
            u_union(u_root(b[i].s,number),u_root(b[i].d,number),number);
            //まだ一度も最小木が作られていないならどの橋を使ったかを記憶する
            if(!flag)
                mst[i] = 1;
            //コストを足していく
            mc += b[i].c;
        }
        i++;
        //最後まで探索して、一つでも同じ集合にない要素があれば、最小木は作れないということになる
        if(i==m)
          if(!allsame(n,number))
             return 0;
    }
    return mc;
}

int main(void){
    int n,m;        //島の数,橋の数
    bridge_t b[M];  //橋の情報
    int mc;         //最初に作った最小木のコスト
    int mc2;        //2回目以降に作る最小木のコスト
    bridge_t temp;  //橋の情報の一時記憶領域
    int number[N];  //親の番号
    int alt[M] = {0};     //オルタナティブな橋の番号(初期値は全て非オルタナティブ))
    int acost=0,abridge=0;    //オルタナティブな橋のコストの和と、オルタナティブな橋の本数の和
    int i,j;

    scanf("%d%d",&n,&m);
    //n要素で初期化(初めは全ての頂点が根)
    for(i=0;i<n;i++)
        number[i] = i+1;
    //橋の始点、終点、コストを入力
    for(i=0;i<m;i++){
        scanf("%d%d%d",&b[i].s,&b[i].d,&b[i].c);
    }
    //qsortによるソート(コストの昇順)
    qsort(b,m,sizeof(bridge_t),cmp);

    //クラスカル法を行う関数を呼び出し
    //全ての要素で最小木を作る
    mc = kruskal(b,n,m,number);
    flag=1;     //１度最小木を作成した

    //numberを初期化
    for(i=0;i<n;i++){
        number[i] = i+1;
    }
    //作った最小木の中で辺を一つだけ取り除き最小木が作れるかどうかで場合分け
    for(j=0;j<m;j++){
        //最初に作った最小木の橋ならばその橋を取り除く
        if(mst[j]){
            rm = j;   //取り除いた橋の番号を記憶
            mc2 = kruskal(b,n,m,number);    //橋を一つ取り除いて最小木を作る
            //ある橋を一つ取り除いて同じコストの最小木を作れないなら、それは不変の橋である
            if(mc < mc2 || mc2 == 0)
                alt[j]=1;
            //numberを初期化しておく
            for(i=0;i<n;i++)
                number[i] = i+1;
        }
        //オルタナティブな橋が見つかれば
        if(alt[j]){
            abridge++;
            acost += b[j].c;
        }
    }
    printf("%d %d\n",abridge,acost);
    
    return 0;
}