zoukankan      html  css  js  c++  java
  • BZOJ 1614 Telephone Lines架设电话线

    二分答案spfa。设>=mid的边为1,<mid的边为0,就可以求出需要免费的道路有多少条。判断一下即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxv 1050
    #define maxe 20050
    #define inf 0x7f7f7f7f
    using namespace std;
    struct edge
    {
        int v,w,nxt,flag;
    }e[maxe];
    int n,m,k,a,b,c,nume=0,g[maxv],minn=inf,maxn=0,ans=inf,prev[maxv],pree[maxv],dis[maxv];
    queue <int> q;
    bool vis[maxv];
    void addedge(int u,int v,int w)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        e[nume].w=w;
        g[u]=nume;
    }
    void lable(int mid)
    {
        for (int i=1;i<=nume;i++)
        {
            if (e[i].w<=mid) 
                e[i].flag=0;
            else e[i].flag=1; 
        }
    }
    int spfa()
    {
        while (!q.empty()) q.pop();
        memset(vis,false,sizeof(vis));
        memset(prev,0,sizeof(prev));
        memset(pree,0,sizeof(pree));
        fill(dis+1,dis+n+1,inf);
        q.push(1);dis[1]=0;vis[1]=true;
        while (!q.empty())
        {
            int head=q.front();
            q.pop();
            for (int i=g[head];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if (dis[v]>dis[head]+e[i].flag)
                {
                    dis[v]=dis[head]+e[i].flag;
                    prev[v]=head;pree[v]=i;
                    if (!vis[v]) 
                    {
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
            vis[head]=false;
        }
        return dis[n];
    }
    void find()
    {
        int left=minn,right=maxn;
        while (left<=right)
        {
            int mid=(left+right)>>1;
            lable(mid);
            int regis1=spfa(),regis2=0,regis3=0;
            if (regis1>k) left=mid+1;
            else
            {
                int now=n;
                while (now!=1)
                {
                    if (e[pree[now]].flag==0) 
                        regis2=max(regis2,e[pree[now]].w);
                    now=prev[now];
                }
                ans=min(ans,regis2);
                right=mid-1;
            }
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            minn=min(minn,c);maxn=max(maxn,c);
            addedge(a,b,c);
            addedge(b,a,c);
        }
        find();
        if (ans!=inf) printf("%d
    ",ans);
        else printf("-1
    ");
        return 0;
    }
  • 相关阅读:
    WebSocket 实战--转
    ELK原理与介绍
    linux命令:使用less从后向前查看日志信息
    Unity创作赛车游戏的四款插件
    Dolly
    shot
    Unity3D获取Android平台的电量
    Unity制作王者荣耀商业级手游
    unity热更新AssetBundle框架设计_框架篇
    喷气传动
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5524626.html
Copyright © 2011-2022 走看看