zoukankan      html  css  js  c++  java
  • 架设电话线

    https://loj.ac/problem/10074

    题目描述

      给出一张n个节点、m条边的加权无向图,求一条从1到n的路径,使第k+1大的边权尽可能小。

    思路

      因为这个答案显然具有单调性,我们考虑对于这个答案进行二分,接下来再想如何确定这个值是否为所求。对于所有大于mid的边,我们把它的边权设为0,把所有小于等于mid的边的边权设为1,那么对于这张图,我们求一次最短路,得到的1~n的最短路径的值就是这个值再所求路径中的排名。或者换一种说法,对于小于等于mid的边权我们需要使用一次免费机会,看到n节点最少要用几次免费机会。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct Edge
    {
        int x,y,w;
    }e[2005];
    int nxt[4005],head[2005],to[4005],w[4005],dis[1005];
    int tot,n,m,p,k;
    bool exist[1005],f;
    void add_edge(int x,int y,int v)
    {
        nxt[++tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        w[tot]=v;
    }
    int spfa()
    {
        memset(dis,0x3f,sizeof(dis));
        memset(exist,0,sizeof(exist));
        queue<int>q;
        q.push(1);exist[1]=1;dis[1]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=nxt[i])
            {
                int v=to[i];
                if(dis[v]>dis[u]+w[i])
                {
                    dis[v]=dis[u]+w[i];
                    if(!exist[v])
                    {
                        q.push(v);
                        exist[v]=1;
                    }
                }
            }
            exist[u]=0;
        }
        if(dis[n]==0x3f3f3f3f)f=1;
        return dis[n];
    }
    bool check(int m)
    {
        memset(head,0,sizeof(head));
        tot=0;
        for(int i=1;i<=p;i++)
        {
            int f=e[i].w<=m?0:1;
    //        cout<<i<<' '<<f<<endl;
            add_edge(e[i].x,e[i].y,f);
            add_edge(e[i].y,e[i].x,f);
        }
        return spfa()<=k;
    }
    int main() 
    {
        int maxx=0;
        scanf("%d%d%d",&n,&p,&k);
        for(int i=1;i<=p;i++)
        {
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
            maxx=max(maxx,e[i].w);
        }
        int l=0,r=maxx;
        while(l<r)
        {
            if(f)break ;
            int mid=l+r>>1;
            if(check(mid))r=mid;
            else l=mid+1;
        }
        if(!f)printf("%d",r);
        else printf("-1");
        return 0;
    }
  • 相关阅读:
    兼容ie和火狐firefox的js调用flash播放器代码特效
    在b/s开发中经常用到的javaScript技术整理
    用javascript+PHP随机显示图片
    1730 博弈
    1198 并查集
    Debug sharepoint
    get your current password on sharepoint(Basci Authentication )
    Site mail box
    Ews get data from exchange shared calender
    upgrade sharepoint 2007 to 2010,2010 to 2013
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11680271.html
Copyright © 2011-2022 走看看