zoukankan      html  css  js  c++  java
  • Cow Routing(最短路spfa)

    题:https://www.luogu.org/problem/P3115

    题意:给出起点A,终点B,N条路线,下面没俩行一个路线,第一行是俩个数,第一个为这条路线的花费,第二个为这条路线经过的点数n,第二行即为n个整数表示这条路径;

    分析:1、题目有说如果要跳转航线就要花费被跳往航线的的费用,所以单单连一条中转的边是错的;

       2、题目范围1000,所以我们暴力建边,但也要建得有思路,对于每一条航线,如果你一直在这条航线上走,花费都是不变的(即为这条航线的cost),所以我们可以认为,对于这条航线的每一个点 i 都可以直接花费cost到 i 后面的点 j ,所以就预处理最小花费和经 过的点数,再添加图的边;

       3、最后spfa一下就好,花费为第一优先级,经过的点数为第二优先级;

    #include<bits/stdc++.h>
    using namespace  std;
    inline int read(){
        int sum=0,x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                x=0;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
            sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
        return x?sum:-sum;
    }
    inline void write(int x){
        if(x<0)
            putchar('-'),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    const int M=1e3+3;
    int maxx=0,tot,head[M],vis[M],a[M];
    ll dis[M][2],cost[M][M],path[M][M];
    struct node{
        int v,nextt;
        ll cost,w;
    }e[M*M];
    void addedge(int u,int v,ll w,ll cost){
        e[tot].v=v;
        e[tot].w=w;
        e[tot].cost=cost;
        e[tot].nextt=head[u];
        head[u]=tot++;
    }
    void spfa(int s,int t){
        for(int i=0;i<=1000;i++)
            dis[i][0]=INF;
        queue<int>que;
        que.push(s);
        dis[s][0]=0;
        while(!que.empty()){
            int u=que.front();
            que.pop();
            vis[u]=0;
            for(int i=head[u];~i;i=e[i].nextt){
                int v=e[i].v;
                if(dis[v][0]>dis[u][0]+e[i].w){
                    dis[v][0]=dis[u][0]+e[i].w;
                    dis[v][1]=dis[u][1]+e[i].cost;
                    if(!vis[v]){
                        vis[v]=1;
                        que.push(v);
                    }
                }
                else if(dis[v][0]==dis[u][0]+e[i].w){
                    if(dis[v][1]>dis[u][1]+e[i].cost)
                        dis[v][1]=dis[u][1]+e[i].cost;
                }
            }
        }
        if(dis[t][0]==INF)
            printf("-1 -1
    ");
        else
            printf("%lld %lld
    ",dis[t][0],dis[t][1]);
    }
    int main(){
        int A=read(),B=read(),t=read();
        memset(head,-1,sizeof(head));
        for(int i=0;i<=1000;i++)
            for(int j=0;j<=1000;j++)
                cost[i][j]=inf;
        maxx=0;
        while(t--){
            int w=read(),n=read();
            for(int i=1;i<=n;i++)
                a[i]=read(),maxx=max(maxx,a[i]);
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                    if(cost[a[i]][a[j]]>w){
                        cost[a[i]][a[j]]=w;
                        path[a[i]][a[j]]=j-i;
                    }
        }
        for(int i=1;i<=maxx;i++)
            for(int j=1;j<=maxx;j++)
                if(cost[i][j]<inf){
                    addedge(i,j,cost[i][j],path[i][j]);
                }
        spfa(A,B);
        return 0;
    }
    View Code
  • 相关阅读:
    【学习小记】一般图最大匹配——带花树算法
    如何检查oracle的归档空间是否满了
    Linux 的计划任务
    转 oracle的热备份和冷备份
    SQLException: Io 异常: Connection refused ERR=12514 ERR=1153异常处理过程
    查看oracle数据库版本
    ORACLE默认实例设置--linux
    oracle查看用户属于哪个表空间
    oracle默认数据库实例
    oracle 查看用户所在的表空间
  • 原文地址:https://www.cnblogs.com/starve/p/11462488.html
Copyright © 2011-2022 走看看