zoukankan      html  css  js  c++  java
  • P1948 [USACO08JAN]电话线Telephone Lines

    传送门

    最短路

    二分+SPFA

    二分最小支出

    如果边权<=最小支出,那么就相当于0

    如果大于最小支出,值设为1

    跑SPFA

    如果dis[n] > k 说明到不了

    否则说明可以到

    模板套进去就好了,没什么好注释的...

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    const int INF=2e9+7;
    const int N=1e6+7;
    int n,m,k;
    int fir[N],from[N],to[N],val[N],cnt;
    inline void add(int a,int b,int c)
    {
        from[++cnt]=fir[a];
        fir[a]=cnt; to[cnt]=b; val[cnt]=c;
    }
    int dis[1007];
    bool vis[1007];
    queue <int> q;
    bool SPFA(int mx)
    {
        memset(dis,0x7f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        q.push(1); vis[1]=1; dis[1]=0;
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            vis[u]=0;
            for(int i=fir[u];i;i=from[i])
            {
                int v=to[i],cost= val[i]>mx ? 1 : 0;
                if(dis[v]>dis[u]+cost)
                {
                    dis[v]=dis[u]+cost;
                    if(!vis[v]) q.push(v),vis[v]=1;
                }
            }
        }
        return dis[n]>k ? 0 : 1;
    }
    int main()
    {
        int a,b,c,mx=-INF,mi=INF;
        cin>>n>>m>>k;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c); add(b,a,c);
            mx=max(mx,c); mi=min(mi,c);
        }
        bool flag=0;
        while(mi<=mx)
        {
            int mid=(mi+mx)>>1;
            if(SPFA(mid)) mx=mid-1,flag=1;
            else mi=mid+1;
        }
        if(!flag) cout<<"-1";
        else cout<<mi;
        return 0;
    }
    二分+SPFA

    还有一种很暴力的方法

    分层图+SPFA

    设dis [ i ] [ j ] 表示到了第 i 个点,用了 j 次免费次数时的最小支出

    然后每次分为用免费次数和不用免费次数两种情况讨论,更新后面的dis

    速度竟然差不多...

    直接看代码就好了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    const int N=1e6+7;
    int n,m,k;
    int fir[N],from[N],to[N],val[N],cnt;
    inline void add(int a,int b,int c)
    {
        from[++cnt]=fir[a];
        fir[a]=cnt; to[cnt]=b; val[cnt]=c;
    }
    int dis[1007][1007];
    bool vis[1007][1007];
    struct node
    {
        int pos,num;//当前位置为pos,用了num次免费次数
    };
    queue <node> q;
    void SPFA()
    {
        memset(dis,0x7f,sizeof(dis));
        q.push((node){1,0}); vis[0][0]=1; dis[1][0]=0;
        while(!q.empty())
        {
            int pos=q.front().pos,num=q.front().num; q.pop();
            vis[pos][num]=0;
            for(int i=fir[pos];i;i=from[i])
            {
                int v=to[i],mx=max(dis[pos][num],val[i]);
                if( dis[v][num]>mx )//不用免费次数
                {
                    dis[v][num]=mx;
                    if(!vis[v][num])
                    {
                        q.push((node){v,num});
                        vis[v][num]=1;
                    }
                }
                if(dis[v][num+1]>dis[pos][num]&&num<=k)//用免费次数
                {
                    dis[v][num+1]=dis[pos][num];
                    if(!vis[v][num+1])
                    {
                        q.push((node){v,num+1});
                        vis[v][num+1]=1;
                    }
                }
            }
        }
    }
    int main()
    {
        int a,b,c;
        cin>>n>>m>>k;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c); add(b,a,c);
        }
        SPFA();
        int ans=1e9+7;
        ans=min(ans,dis[n][k]);
        if(ans==1e9+7) cout<<"-1";
        else cout<<ans;
        return 0;
    }
    分层图+SPFA
  • 相关阅读:
    js 跳转链接
    reg.test is not a function 报错
    html中button自动提交表单?
    mysql主从复制及双主复制
    nginx反向代理后端web服务器记录客户端ip地址
    mysql多实例-主从复制安装
    LVS+Keepalived高可用负载均衡集群架构实验-01
    debug调试
    常用网站总结
    项目部署
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9692191.html
Copyright © 2011-2022 走看看