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
#include
#include
#include
#include
#include
#include
#include
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;
vectorans,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_queueq;
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;
queueq;
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