1. 程式人生 > >codeforce 1076 D. Edge Deletion【堆優化的Dij還會被卡】

codeforce 1076 D. Edge Deletion【堆優化的Dij還會被卡】

文章目錄

題目連結:

http://codeforces.com/contest/1076/problem/D

題意:N個點,M條邊,選擇K條邊留下來,使得留下來的這些節點到1號點的最短路不變,並且要使留下來的點最多

因為要連成一顆樹,所以最多就是K+1個節點,跑個Dij,然後順著選K個點就行了
這道題最大的收穫是:堆優化的Dij也會被卡,要標記看是不是在佇列裡面,以前不是一直說不用標記啥的嘛,也沒出現過問題,結果今天。。。幸好彭老闆先補這道題,然後找出問題所在T_T
看別人的程式碼直接用set了,不在佇列裡就直接erase了

#include
"bits/stdc++.h"
using namespace std; typedef long long LL; const int maxn=1e6+5; const int MOD=1e9+7; LL inf=1e15; int N,M,K; int Pre[maxn]; struct Edge { LL t,v,nxt,id; Edge() {} Edge(LL t,LL v):t(t),v(v) {} Edge(LL t,LL v,LL id):t(t),v(v),id(id) {} bool operator<(const Edge tp)const { return
v>tp.v; } }; Edge E[maxn<<2]; int head[maxn<<1]; int tot; void AddEdge(int aa,int bb,LL val,LL id) { E[++tot].t=bb; E[tot].id=id; E[tot].v=val; E[tot].nxt=head[aa]; head[aa]=tot; } priority_queue<Edge>que; LL dis[maxn<<1]; void Dij(int st) { while(!que.empty())que.
pop(); for(int i=1; i<=N+M; i++)dis[i]=inf; dis[st]=0; que.push(Edge(st,0)); while(!que.empty()) { int u=que.top().t; que.pop(); for(int i=head[u]; i!=-1; i=E[i].nxt) { int t=E[i].t; int v=E[i].v; if(dis[u]+v<dis[t]) { Pre[t]=u; dis[t]=dis[u]+v; que.push(Edge(t,dis[t])); } } } } vector<int>ans; void dfs(int u,int pre) { for(int i=head[u];i!=-1;i=E[i].nxt) { LL t=E[i].t; if(t==pre)continue; if(Pre[t]!=u)continue; int id=E[i].id; if(K>0) { K--; ans.push_back(id); dfs(t,u); } } } int main() { while(cin>>N>>M>>K) { ans.clear(); tot=0; memset(head,-1,sizeof head); for(LL i=1;i<=M;i++) { int u,v; LL w; scanf("%d%d%I64d",&u,&v,&w); AddEdge(u,v,w,i); AddEdge(v,u,w,i); } Dij(1); vector<int>tp; dfs(1,-1); cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++)cout<<ans[i]<<" "; cout<<endl; } } */