zoukankan      html  css  js  c++  java
  • Codeforces 1076D Edge Deletion(最短路树)

    题目链接:Edge Deletion

    题意:给定一张n个顶点,m条边的带权无向图,已知从顶点1到各个顶点的最短路径为di,现要求保留最多k条边,使得从顶点1到各个顶点的最短距离为di的顶点最多。输出m条边中需要保留的边的编号。

    题解:先跑一遍最短路,在松弛操作时,存父子关系和边,在以这些关系建立新图(树),因为在松弛操作时存的关系,所以能保证是最短路径,最后DFS输出k条边即可。

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int N=3e5+10;
     8 
     9 struct qnode{
    10     ll v,w;
    11     qnode(){}
    12     qnode(ll v,ll w):v(v),w(w){}
    13     bool operator < (const qnode& b) const{
    14         return w>b.w;
    15     }
    16 };
    17 
    18 struct node{
    19     ll nxt,v,w;
    20     node(){}
    21     node(ll nxt,ll v,ll w):nxt(nxt),v(v),w(w){}
    22 };
    23 
    24 ll n,m,k,tot;
    25 node edge[N<<1];
    26 ll head[N],d[N];
    27 qnode cur,tmp;
    28 bool vis[N];
    29 priority_queue <qnode> Q;
    30 pair <ll,ll> fa[N];
    31 vector <int> g[N],ans;
    32 
    33 void add_edge(ll u,ll v,ll w){
    34     edge[tot]=node(head[u],v,w);
    35     head[u]=tot++;
    36 }
    37 
    38 void init(){
    39     tot=1;
    40     memset(head,0,sizeof(head));
    41 }
    42 
    43 void dijkstra(ll s){
    44     for(int i=0;i<N;i++) d[i]=1e18;
    45     d[s]=0;
    46     Q.push(qnode(s,0));
    47     while(!Q.empty()){
    48         cur=Q.top();
    49         Q.pop();
    50         ll u=cur.v;
    51         if(vis[u]) continue;
    52         vis[u]=true;
    53         for(ll i=head[u];i;i=edge[i].nxt){
    54             ll v=edge[i].v;
    55             ll w=edge[i].w;
    56             if(d[u]+w<d[v]){
    57                 d[v]=d[u]+w;
    58                 fa[v]=make_pair(u,(i+1)/2);
    59                 Q.push(qnode(v,d[v]));
    60             }
    61         }
    62     }
    63 }
    64 
    65 void dfs(int u){
    66     if(k==0) return;
    67     if(u!=1){
    68         ans.push_back(fa[u].second);
    69         k--;
    70     }
    71     for(ll v:g[u]) dfs(v);
    72 }
    73 
    74 int main(){
    75     init();
    76     scanf("%lld%lld%lld",&n,&m,&k);
    77     for(ll i=1;i<=m;i++){
    78         ll u,v,w;
    79         scanf("%lld%lld%lld",&u,&v,&w);
    80         add_edge(u,v,w);
    81         add_edge(v,u,w);
    82     }
    83     dijkstra(1);
    84     for(ll i=2;i<=n;i++) g[fa[i].first].push_back(i);
    85     dfs(1);
    86     printf("%d
    ",ans.size());
    87     for(ll u:ans) printf("%lld ",u);
    88     printf("
    ");
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    第01组 团队Git现场编程实战
    2019 SDN上机第1次作业
    第二次结对编程作业
    团队项目-需求分析报告
    团队项目-选题报告
    2019 SDN阅读作业
    2019 SDN上机第3次作业
    2019 SDN上机第2次作业
    2019 SDN上机第1次作业
    OpenDayLight安装Features
  • 原文地址:https://www.cnblogs.com/pavtlly/p/9959556.html
Copyright © 2011-2022 走看看