zoukankan      html  css  js  c++  java
  • Codeforces Round #303 (Div. 2) E

    五道水题,但要手快才好。。。我手慢了,E题目都没看完TAT....

    想了一发,很水,就是一遍Dijk即可,使用优先队列,同时记录由哪条边转移而来

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #define LL long long
    using namespace std;
    
    const int MAXN=300050;
    
    struct Edge{
        int u,v,w,i,next;
    }edge[MAXN*2];
    int weight[MAXN],head[MAXN],tot;
    int n,m; int chose[MAXN];
    LL dis[MAXN]; bool vis[MAXN];
    
    struct Node{
        int u; LL d;
        Node(){}
        Node(int uu,LL dd){u=uu,d=dd;}
        bool operator<(const Node &a)const{
            return d>a.d;
        }
    };
    
    vector <int>ans;
    priority_queue<Node>pq;
    LL cur;
    
    void addedge(int u,int v,int w,int i){
        edge[tot].u=u; edge[tot].v=v;
        edge[tot].w=w; edge[tot].i=i;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    
    void Dijk(int r){
        cur=0;
        for(int i=1;i<=n;i++) dis[i]=1ll<<62;
        dis[r]=0;
        memset(chose,0,sizeof(chose));
        memset(vis,false,sizeof(vis));
        ans.clear();
        pq.push(Node(r,0));
        while(!pq.empty()){
            Node tmp=pq.top(); pq.pop();
            if(vis[tmp.u]) continue;
            if(tmp.u!=r){
                cur+=weight[chose[tmp.u]];
                ans.push_back(chose[tmp.u]);
            }
            LL d=tmp.d;
            vis[tmp.u]=true;
            for(int e=head[tmp.u];e!=-1;e=edge[e].next){
                int v=edge[e].v;
                if(!vis[v]){
                    if(d+edge[e].w<dis[v]){
                        dis[v]=d+edge[e].w;
                        chose[v]=edge[e].i;
                        pq.push(Node(v,dis[v]));
                    }
                    else if(d+edge[e].w==dis[v]){
                        if(edge[e].w<weight[chose[v]]){
                            chose[v]=edge[e].i;
                        }
                    }
                }
            }
        }
        sort(ans.begin(),ans.end());
        cout<<cur<<endl;
        int len=ans.size();
        if(len>0){
            printf("%d",ans[0]);
            for(int i=1;i<len;i++)
            printf(" %d",ans[i]);
            printf("
    ");
        }
    }
    
    int main(){
        int u,v,w;
        while(scanf("%d%d",&n,&m)!=EOF){
            memset(head,-1,sizeof(int)*(n+10));
            tot=0;
            weight[0]=1e9+1000000;
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w,i);
                addedge(v,u,w,i);
                weight[i]=w;
            }
            scanf("%d",&u);
            Dijk(u);
        }
        return 0;
    }
  • 相关阅读:
    指针作为函数参数
    二级指针与多级指针
    指针数组与数组指针
    指针与数组
    指针引入
    Python中调用自然语言处理工具HanLP手记
    HanLP中的人名识别分析详解
    自然语言处理中的分词问题总结
    Hanlp实战HMM-Viterbi角色标注中国人名识别
    Hanlp中使用纯JAVA实现CRF分词
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4518290.html
Copyright © 2011-2022 走看看