CodeForces1076D、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条边,最多能保留K条边。原图上每个点的最短路为di。现在删除了边后,使得到点1的距离仍为di的点数量最多的情况下,输出应该保留的K条边的编号。

 

三、大致思路

先跑1到所有点的最短距离。然后从1再跑一次BFS,遇到遍历到当前边的情况是最短路上的一条边的时候,将这条边加入答案。需要注意的是数据的范围会爆int。

 

四、代码

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
using namespace std;
typedef long long LL;

const LL inf=0x3f3f3f3f3f3f3f3f;
const int maxn=300005;
const int maxm=300005*2;
int n,m,K;
int head[maxm];
LL dis[maxn];
bool vis[maxn];
int edgenum;
vector<int>ans,ee[maxn];
typedef struct
{
	int v;
	LL cost;
}Node;
bool operator <(const Node &a,const Node &b)
{
	return a.cost>b.cost;
}

struct Edge
{
    int u,to,next,id;
    LL cost;
}e[maxm];
void add(int from,int to,LL cost,int id)
{
	e[edgenum].next=head[from];
	e[edgenum].to=to;
	e[edgenum].cost=cost;
	e[edgenum].id=id;
	e[edgenum].u=from;
	head[from]=edgenum++;
}
void read()
{
    for(int i=1;i<=m;i++)
    {
        int u,v;
        LL w;
        scanf("%d %d %lld",&u,&v,&w);
        add(u,v,w,i);
        add(v,u,w,i);
    }
}
void init()
{
    edgenum=0;
    memset(head,-1,sizeof(head));
    ans.clear();
}
void Dijkstra()
{
    memset(vis,false,sizeof(vis));
	for(int i=1;i<=n;i++)dis[i]=inf;
	Node t;
	priority_queue<Node>q;
	t.cost=0;
	dis[1]=0;
	t.v=1;
	q.push(t);
	while(!q.empty())
	{
		t=q.top();
		q.pop();
		if(vis[t.v])continue;
		vis[t.v]=true;
		for(int i=head[t.v];i!=-1;i=e[i].next)
		{
			if(!vis[e[i].to]&&dis[e[i].to]>dis[t.v]+e[i].cost)
			{
				Node temp;
				temp.v=e[i].to;
				temp.cost=e[i].cost+t.cost;
				dis[e[i].to]=dis[t.v]+e[i].cost;
				q.push(temp);
			}
		}
	}
	return ;
}
void BFS(int start)
{
    memset(vis,false,sizeof(vis));
    vis[start]=true;
    queue<int>q;
    q.push(start);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        for(int i=head[t];i!=-1;i=e[i].next)
        {
            int to=e[i].to;
            if(!vis[to]&&dis[to]==dis[t]+e[i].cost)
            {
                vis[to]=true;
                ans.push_back(e[i].id);
                q.push(to);
            }
        }
    }
}
int main()
{
    while(scanf("%d %d %d",&n,&m,&K)!=EOF)
    {
        init();
        read();
        Dijkstra();
        BFS(1);
        int put=ans.size();
        if(K<put)put=K;
        printf("%d\n",put);
        for(int i=0;i<put;i++)
            printf("%d ",ans[i]);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值