1076D Edge Deletion 【最短路】
题目:戳这里
题意:求出1到所有点的最短路径后,把边减到小于等于k条,问保留哪些边可以使仍存在的最短路径最多。
解题思路:这题就是考求最短路的原理。比如dijkstra,用优先队列优化后存在队列中的前k条边就是答案。因为可以优先队列维护最小值,因此放进队列中的边一定是最短的。借这道题又复习了下dijkstra。
附本人代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 typedef long long ll; 6 const int Max = 3e5+10; 7 const ll inf = 1e18; 8 using namespace std; 9 struct edge{int to,id; ll cost;}; 10 vector<edge>G[Max]; 11 ll d[Max]; 12 struct nod { 13 ll x; 14 int y, id; 15 nod() {} 16 nod(ll xx, int yy, int Id) { 17 x = xx,y = yy, id = Id; 18 } 19 bool friend operator < (nod a, nod b) { 20 return a.x > b.x; 21 } 22 }; 23 int n,m, k; 24 int anslen = 0; 25 int ans[Max]; 26 void dijkstra(){ 27 priority_queue<nod >que; 28 d[0]=0; 29 que.push(nod(0,0,0)); 30 while(!que.empty()){ 31 nod p=que.top();que.pop(); 32 int v=p.y; 33 if(d[v]<p.x) continue; 34 if(anslen == k) break; 35 if(p.id != 0) 36 ans[++anslen] = p.id; 37 for(int i=0;i<G[v].size();i++){ 38 edge e=G[v][i]; 39 if(d[e.to]>d[v]+e.cost){ 40 d[e.to]=d[v]+e.cost; 41 que.push(nod(d[e.to],e.to,e.id)); 42 } 43 } 44 } 45 } 46 int main(){ 47 48 scanf("%d %d %d",&n,&m, &k); 49 fill(d,d +Max,inf); 50 int a,b; 51 ll c; 52 for(int i=0;i<m;i++){ 53 scanf("%d %d %lld",&a,&b,&c); 54 a-=1; 55 b-=1; 56 edge e; 57 e.to=b;e.cost=c; 58 e.id = i+1; 59 G[a].push_back(e); 60 e.to=a; 61 G[b].push_back(e); 62 } 63 dijkstra(); 64 printf("%d\n", anslen); 65 for(int i = 1; i <= anslen; ++i) { 66 printf("%d ", ans[i]); 67 } 68 69 return 0; 70 }