zoukankan      html  css  js  c++  java
  • P1828 香甜的黄油 Sweet Butter 最短路 寻找一个点使得所有点到它的距离之和最小

    P1828 香甜的黄油 Sweet Butter

    闲来无事 写了三种最短路(那个Floyed是不过的)

    题目描述

    农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。

    农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。

    农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)

    输入格式

    第一行: 三个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450)

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

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

    输出格式

    一行 输出奶牛必须行走的最小的距离和

    输入输出样例

    输入 #1
    3 4 5
    2
    3
    4
    1 2 1
    1 3 5
    2 3 7
    2 4 3
    3 4 5
    输出 #1
    8

    说明/提示

    {样例图形

              P2  
    P1 @--1--@ C1
             |
             | 
           5  7  3
             |   
             |     C3
           C2 @--5--@
              P3    P4
    

    } {说明:

    放在4号牧场最优

    }

    Floyed n^3

    Floyed(超时啦 只有63分)

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=805,INF=0x3f3f3f3f;
    int N,P,C;
    int c[maxn],dis[maxn][maxn];
    inline void Min(int &x,int y){
        if(x>y) x=y;
    }
    void Floyd(){
        for(int k=1;k<=P;k++)
            for(int i=1;i<=P;i++) if(i!=k)
                for(int j=1;j<=P;j++)if(i!=j&&j!=k)
                    Min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    int main() 
    {
        freopen("butter.in","r",stdin);freopen("butter.out","w",stdout);
        scanf("%d%d%d",&N,&P,&C);
        for(int i=1;i<=N;i++){
            int x;scanf("%d",&x);
            c[x]++;
        }
        memset(dis,0x3f,sizeof(dis));//这里的一个3f 等于外面的4个3f
        for(int i=1;i<=P;i++) dis[i][i]=0;
        for(int i=1;i<=C;i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            Min(dis[x][y],z);Min(dis[y][x],z);//可能有重边 取更小的那一个 
        } 
        Floyd();int ans=0x3f3f3f3f;
        for(int i=1;i<=P;i++){
            int res=0;
            for(int j=1;j<=P;j++) res+=c[j]*dis[j][i];
            Min(ans,res);
        }
        cout<<ans;
        return 0;
    }

    Dijkstra  只能用于有正权边的图   可有正环 不能有负环   Dijkstra n+mlogm    (n可以忽略不计)

    //正解!
    #include<bits/stdc++.h>
    #define pa pair<int,int>
    #define maxn 805
    using namespace std;
    vector<int> v[maxn],w[maxn];
    priority_queue<pa,vector<pa>,greater<pa> > q;
    int dis[maxn],c[maxn];
    bool vis[maxn];
    int N,P,C;
    void Dijkstra(int s){
        memset(dis,0x3f,sizeof(dis));dis[s]=0;
        memset(vis,0,sizeof(vis));
        while(!q.empty())
            q.pop();
        q.push(make_pair(0,s));
        while(!q.empty()){
            int x=q.top().second;
            q.pop();
            if(vis[x]) continue;
            vis[x]=1;
            for(int i=0;i<v[x].size();i++){
                int y=v[x][i];
                if(dis[x]+w[x][i]<dis[y])
                {
                    dis[y]=dis[x]+w[x][i];
                    q.push(make_pair(dis[y], y));
                }
            }
        }
    }
    int main()
    {
        freopen("butter.in","r",stdin);freopen("butter.out","w",stdout);
        scanf("%d%d%d",&N,&P,&C);
        for(int i=1;i<=N;i++){
            int x;scanf("%d",&x);
            c[x]++;
        }
        for(int i=1;i<=C;i++)    {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            v[x].push_back(y);v[y].push_back(x);w[x].push_back(z);w[y].push_back(z);
        }
        int ans=0x3f3f3f;
        for(int i=1;i<=P;i++){
            Dijkstra(i);int res=0;
            for(int j=1;j<=P;j++)
                res+=dis[j]*c[j];
            ans=min(ans,res);
        }
        cout<<ans;
        return 0;
    }

    SPFA   上限n*m

    #include<bits/stdc++.h>
    #define maxn 805
    using namespace std;
    bool bein[maxn];int dis[maxn];
    vector<int> v[maxn],w[maxn];int N,P,C;int c[maxn];
    void SPFA(int S){
        memset(dis,0x3f,sizeof(dis));
        queue<int> q; 
        dis[S]=0;
        q.push(S);
        bein[S]=true;
        while(!q.empty()){
            int x=q.front();q.pop();bein[x]=false;
            for(int i=0;i<v[x].size();i++){
                int y=v[x][i];
                if(dis[y]>dis[x]+w[x][i]){
                    dis[y]=dis[x]+w[x][i];
                    if(!bein[y]){
                        bein[y]=true;
                        q.push(y);
                    }
                }
            }
        }
    }
    int main()
    {
        freopen("butter.in","r",stdin);freopen("butter.out","w",stdout);
        scanf("%d%d%d",&N,&P,&C);
        for(int i=1;i<=N;i++){
            int x;scanf("%d",&x);
            c[x]++;
        }
        for(int i=1;i<=C;i++)    {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            v[x].push_back(y);v[y].push_back(x);w[x].push_back(z);w[y].push_back(z);
        }
        int ans=0x3f3f3f;
        for(int i=1;i<=P;i++){
            SPFA(i);int res=0;
            for(int j=1;j<=P;j++)
                res+=dis[j]*c[j];
            ans=min(ans,res);
        }
        cout<<ans;
        
        return 0;
    }

     

  • 相关阅读:
    springcloud
    redis实现Session
    深入理解Dip Ioc Di以及Ioc容器
    SQL Server 索引维护 索引碎片 填充因子
    SQL Server 非聚集索引的覆盖,连接交叉和过滤
    SQL Server 索引 聚集索引、非聚集索引、堆
    T-SQL存储过程
    T-SQl 批处理
    T-SQl 游标
    T-SQL 控制流语句
  • 原文地址:https://www.cnblogs.com/Tidoblogs/p/11328158.html
Copyright © 2011-2022 走看看