1. 程式人生 > >Codeforces Edge Deletion 最短路+bfs

Codeforces Edge Deletion 最短路+bfs

D. Edge Deletion

time limit per test

2.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an undirected connected weighted graph consisting of nn vertices and mm edges. Let's denote the length of the shortest path from vertex 11 to vertex ii as didi.

You have to erase some edges of the graph so that at most kk edges remain. Let's call a vertex ii good if there still exists a path from 11 to iiwith length didi after erasing the edges.

Your goal is to erase the edges in such a way that the number of good vertices is maximized.

Input

The first line contains three integers nn, mm and kk (2≤n≤3⋅1052≤n≤3⋅105, 1≤m≤3⋅1051≤m≤3⋅105, n−1≤mn−1≤m, 0≤k≤m0≤k≤m) — the number of vertices and edges in the graph, and the maximum number of edges that can be retained in the graph, respectively.

Then mm lines follow, each containing three integers xx, yy, ww (1≤x,y≤n1≤x,y≤n, x≠yx≠y, 1≤w≤1091≤w≤109), denoting an edge connecting vertices xx and yy and having weight ww.

The given graph is connected (any vertex can be reached from any other vertex) and simple (there are no self-loops, and for each unordered pair of vertices there exists at most one edge connecting these vertices).

Output

In the first line print ee — the number of edges that should remain in the graph (0≤e≤k0≤e≤k).

In the second line print ee distinct integers from 11 to mm — the indices of edges that should remain in the graph. Edges are numbered in the same order they are given in the input. The number of good vertices should be as large as possible.

Examples

input

Copy

3 3 2
1 2 1
3 2 1
1 3 3

output

Copy

2
1 2 

input

Copy

4 5 2
4 1 8
2 4 1
2 1 3
3 4 9
3 1 5

output

Copy

2
3 2 

題目大意:一個圖N個點M條雙向邊。設各點到點1的距離為di,保證滿足條件刪除M-K條邊之後使得到點1的距離仍為di的點數量最多的情況下,輸出剩餘的K條邊的編號(按輸入順序)

用dijkstra跑出最短路樹,然後在樹上bfs,貪心地保留邊就好了。

#include <bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int Maxn = 3e5 + 10 ;

int n, m, k ;

struct Node{
    int v ;
    ll dis ;
    Node(int _v = 0, ll _dis = 0) : v(_v), dis(_dis){}
    bool operator < (const Node &a) const {
        return dis > a.dis ;
    }
};

struct Edge{
    int id, v ;
    ll w ;
    Edge (int _id = 0, int _v = 0 , ll _w = 0) : id (_id), v(_v), w(_w){}

};

vector < Edge > ve[Maxn] ;
bool vis[Maxn] ;
ll dis[Maxn] ;
int fat[Maxn], faEdge[Maxn] ;

void Add_edge(int ri, int u, int v, ll w){
    ve[u].push_back(Edge(ri, v, w)) ;
    ve[v].push_back(Edge(ri, u, w)) ;
}

void Dijkstra(){
    memset(dis, 0x3f, sizeof(dis)) ;
    memset(vis, false, sizeof(vis)) ;
    dis[1] = 0 ;
    fat[1] = 1 ;
    priority_queue < Node > que ;
    que.push(Node(1, 0)) ;
    while (!que.empty()){
        Node New = que.top() ;
        que.pop() ;
        int u = New.v ;
        if (vis[u]) continue ;
        vis[u] = true ;
        for (int i = 0; i < (int) ve[u].size(); i++){
            int id = ve[u][i].id ;
            int v = ve[u][i].v ;
            ll w = ve[u][i].w ;
            if (!vis[v] && dis[v] > dis[u] + w){
                dis[v] = dis[u] + w ;
                fat[v] = u ;
                faEdge[v] = id ;
                que.push(Node(v, dis[v])) ;
            }
        }
    }
}

vector < int > son[Maxn] ;
vector < int > ans ;

void Bfs(){
    queue < int > Que ;
    Que.push(1) ;
    while (!Que.empty() && k > 0){
        int u = Que.front() ;
        Que.pop() ;
        for (int i = 0; i < (int)son[u].size(); i++){
            int v = son[u][i] ;
            if (k > 0){
                ans.push_back(faEdge[v]) ;
                Que.push(v) ;
                k-- ;
            }
            else break ;
        }
    }
}

int main (){
    cin >> n >> m >> k ;
    for (int i = 1; i <= m; i++){
        int u, v ;
        ll w ;
        cin >> u >> v >> w ;
        Add_edge(i, u, v, w) ;
    }
    Dijkstra() ;
//    for (int i = 1; i <= n; i++){
//        cout << i  << " " ;
//    }
//    cout << endl ;
//    for (int i = 1; i <= n; i++){
//        cout << fat[i] << " " ;
//    }
    cout << endl ;
    for (int i = 2; i <= n; i++){
        son[fat[i]].push_back(i) ;
    }
    Bfs() ;
    cout << ans.size() << endl ;
    bool flag = true ;
    for (int i = 0; i < (int) ans.size(); i++){
        if (flag) flag = false ;
        else  cout << " " ;
        cout << ans[i] ;
    }
    cout << endl ;
    return 0 ;
}