zoukankan      html  css  js  c++  java
  • 【刷题】【最短路】架设电话线

    在加权无向图上求出一条从1号结点到n号结点的路径,使路径上第k+1大的边权尽量小。

    解读:二分搜索答案,求>mid的边的数量最好是k,否则就少一点点

    #include<cstdio>
    #include<cstdlib>
    #include<vector>
    #include<queue>
    #include<cstring>
    using namespace std;
    int n,m,k;
    const int N=1003;
    struct node
    {
        int v,w;
        node(int vv,int ww)
        { v=vv,w=ww; }
        node(){}
    };
    vector <node > g[N];
    int sz[N];
    
    struct nd
    {
        int v,d,cnt;
        bool operator < (const nd & o) const
        { return d>o.d; }
        nd(int vv,int dd,int c)
        { v=vv,d=dd,cnt=c; }
        nd(){}
    };
    priority_queue <nd> q;
    int dis[N][1003],mx;//就是求小于mid的边是不是 大于等于 k 
    bool check(int mid)
    {
        while(!q.empty() ) q.pop() ;
        memset(dis,-1,sizeof(dis));
        dis[1][0]=0,q.push(nd(1,0,0));
        
        int ans=k+1;
        while(!q.empty() )
        {
            nd t=q.top() ;q.pop() ;
            if(t.d !=dis[t.v ][t.cnt ]) continue;
            if(t.v ==n)
            {
                ans=t.cnt ;
                break;
            }
            
            for(int i=0;i<sz[t.v ];i++)
            {
                int nx=g[t.v ][i].v ,dd,stp=t.cnt ;
                if(g[t.v ][i].w > mid) dd=dis[t.v ][stp],stp++;
                else dd=max(g[t.v ][i].w ,dis[t.v ][stp]);
                
                if(stp>k) continue;
                if(dd < dis[nx][stp] || dis[nx][stp]==-1)
                {
                    dis[nx][stp]=dd;
                    q.push(nd(nx,dd,stp)); 
                }
            }
        }
        
        return ans<=k;
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        int u,v,w;
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            g[u].push_back(node(v,w));
            g[v].push_back(node(u,w));  
        }
        for(int i=1;i<=n;i++)
            sz[i]=g[i].size() ;
        
        int l=0,r=1<<30,ans;
        if(!check(r))
            printf("-1
    ");
        else
        {    
            while(l<r)
            {
                int mid=(l+r)>>1;
                if(check(mid)) r=mid;
                else l=mid+1;
            }
            printf("%d
    ",l);
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    正则 匹配 HTML 标签
    webpack 打包图片 能否提高加载速度
    禁止手机浏览器左右滑屏 后退 前进
    Objective-C--@property,@synthesize关键字介绍
    ios--绘图介绍
    iOS--为视图添加阴影
    iOS--iOS7摄像头识别二维码功能
    iOS--日历事件的获取和添加
    iOS-#ifdef DEBUG代码块介绍
    如何将你的程序打包成ipa
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11669601.html
Copyright © 2011-2022 走看看