zoukankan      html  css  js  c++  java
  • YbtOj练习:二分5 飞离地球

    除看这道题,以为就是很简单的二分+判断负环

    但是数次0分告诉我哪有你想的那么简单

    我们在求最短路的过程中,应该把那些不同时满足1.与起点联通2.与终点联通的点删除。  一旦我们把这些点考虑进去,且这些点上还有负环时,对答案的影响就是致命的。

    比如说这种情况

     而如果终点不满足上述条件,我们就可以直接输出-1了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=105,M=10005,inf=0x3f3f3f3f;
    int h[N],e[M],ne[M],w[M];
    int tot,n,m,T,dis[N];
    bool vis[N],useful[N];//useful表示是否同时满足两个约束条件 
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    inline void add(int a,int b,int c)
    {
        ne[++tot]=h[a];
        e[tot]=b;
        w[tot]=c;
        h[a]=tot;
    }
    inline void dfs(int x)
    {
        vis[x]=1;
        for(int i=h[x];i;i=ne[i])
        {
            int t=e[i];
            if(!vis[t])dfs(t);
        }
    }
    inline bool judge(int now,int x)  //判断负环 
    {
        vis[now]=1;
        for(int i=h[now];i;i=ne[i])
        {
            int t=e[i];
            if(dis[t]>dis[now]+w[i]+x&&useful[t]) 
            {
                if(vis[t]) return true;  //被重复更新,出现负环 
                dis[t]=dis[now]+w[i]+x;
                if(judge(t,x)) return true;
            }
        }
        vis[now]=0;
        return false;
    }
    inline void SPFA(int x)
    {
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(1);dis[1]=0;vis[1]=1;
        while(!Q.empty())
        {
            int tmp=Q.front();Q.pop();vis[tmp]=0;
            for(int i=h[tmp];i;i=ne[i])
            {
                int t=e[i];
                if(dis[t]>dis[tmp]+w[i]+x&&useful[t])
                {
                    dis[t]=dis[tmp]+w[i]+x;
                    Q.push(t);
                    vis[t]=1;
                }
            }
        }
    }
    inline bool check(int x)
    {
        for(int i=1;i<=n;i++)
        if(useful[i])
        {
            memset(dis,0,sizeof(dis));//判断负环不需要把dis初始化成正无穷 
            memset(vis,0,sizeof(vis));
            if(judge(i,x)) return false;
        }
        SPFA(x);
        if(dis[n]>=0&&dis[n]<=inf) return true;
        return false;
    }
    int main()
    {
        T=read();
        while(T--)
        {
            int ans=0;
            int l=-1e6,r=1e6;
            memset(h,0,sizeof(h));
            memset(useful,0,sizeof(useful));
            tot=0;
            n=read();m=read();
            for(int i=1;i<=m;i++)
            {
                int a=read(),b=read(),c=read();
                add(a,b,c);
            }
            memset(vis,0,sizeof(vis));
            dfs(1);
            for(int i=1;i<=n;i++)
            if(vis[i]) useful[i]=1;
            for(int i=1;i<=n;i++)
            if(useful[i]) 
            {
                memset(vis,0,sizeof(vis));
                dfs(i);
                if(!vis[n]) useful[i]=0;
            }
            if(!useful[n])   //特判 
            {
                printf("-1
    ");
                continue;
            }
            while(l<r)
            {
                int mid=l+r>>1;
                if(check(mid)) r=mid,ans=dis[n];
                else l=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第三十七节:系统证书管理和gRPC基于数字证书的认证和授权
    第三十六节:gRPC身份认证和授权(JWT模式 和 集成IDS4)
    第三十五节:gRPC拦截器、版本控制、安全性、日志集成
    第三十四节:.Proto文件剖析、gRPC的四种传输模式(一元和流式)和常用配置
    第三十三节:.Net Core下的gRPC详细介绍
    IIS7通过AppCmd.exe管理IIS
    MySql新增列的时候判断是否存在
    PowerDesigner从Excel导入表
    Java中Base64.encodeBase64URLSafe在C#的实现
    【产品方法论】字节跳动
  • 原文地址:https://www.cnblogs.com/smartljy/p/13489271.html
Copyright © 2011-2022 走看看