• 香甜的黄油


    链接

    https://www.acwing.com/problem/content/1129/

    题目

    农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖。

    把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。

    当然,他将付出额外的费用在奶牛上。

    农夫John很狡猾,就像以前的巴甫洛夫,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。

    他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。

    农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。

    给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。

    数据保证至少存在一个牧场和所有牛所在的牧场连通。

    输入格式
    第一行: 三个数:奶牛数 N,牧场数 P,牧场间道路数 C。

    第二行到第 N+1 行: 1 到 N 头奶牛所在的牧场号。

    第 N+2 行到第 N+C+1 行:每行有三个数:相连的牧场A、B,两牧场间距 D,当然,连接是双向的。

    输出格式
    共一行,输出奶牛必须行走的最小的距离和。

    数据范围
    (1≤N≤500, 2≤P≤800, 1≤C≤1450, 1≤D≤255)
    输入样例:

    3 4 5
    2
    3
    4
    1 2 1
    1 3 5
    2 3 7
    2 4 3
    3 4 5
    

    输出样例:

    8
    

    思路

    Dijkstra时间复杂度为(O(e+vlogv)),以每个点为起点求一次Dijkstra复杂度为(O(v*(e+vlogv))=O(500*2000)=O(1000000)).

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2510,M=6210;
    typedef pair<int,int> PII;
    struct eg{
        int v,c,nex;
    }edge[M*2];
    int head[N],cnt;
    void addedge(int u,int v,int c){
        edge[++cnt]=(eg){v,c,head[u]};
        head[u]=cnt;
    }
    int dis[N],vis[N];
    priority_queue<PII> heap;
    vector<int> v;
    int n,m,s,t;
    int dij(int s){
        memset(dis,0x3f,sizeof dis);
        memset(vis,0,sizeof vis);
        dis[s]=0;
        heap.push({0,s});
        while(!heap.empty()){
            int u=heap.top().second;
            heap.pop();
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=head[u];~i;i=edge[i].nex){
                int v=edge[i].v,c=edge[i].c;
                if(dis[v]>dis[u]+c){
                    dis[v]=dis[u]+c;
                    heap.push({-dis[v],v});
                }
            }
        }
        int res=0;
        for(int i=0;i<v.size();++i) res+=dis[v[i]];
        return res;
    }
    int main(){
        memset(head,-1,sizeof head);
        int k;
        cin>>k>>n>>m;
        for(int i=1,x;i<=k;++i) {
            cin>>x;
            v.push_back(x);
        }
        for(int i=1;i<=m;++i){
            int u,v,c;
            cin>>u>>v>>c;
            addedge(u,v,c);
            addedge(v,u,c);
        }
        int ans=1000000000;
        for(int i=1;i<=n;++i){
            ans=min(ans,dij(i));
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    Exection throws和throw
    Exection(二)
    JAVA-Exception
    IDEA初见---输出HelloWorld,并打包成jar包
    Centos6.5安装Tomcat
    Centos6.5下装ZooKeeper
    LInux下装jdk
    python作业高级FTP
    tcp黏包
    计算器
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12743590.html
Copyright © 2020-2023  润新知