zoukankan      html  css  js  c++  java
  • 牛客假期训练三:处女座的比赛资格(拓扑排序求有负边的最短路径)

    题目链接:传送门

    思路:因为存在负值边,所以一开始就想广搜求出最短路径,结果错了,后来发现是没用好bfs。

    题解上说可以用拓扑排序求带负权值边的最短路径,这次get到了。

    就是邻接表的使用还不太熟悉,代码是参考排名第一的大佬的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int maxn = 2e5+10;
    const int INF = 0x3f;
    int u[maxn],v[maxn],c[maxn],ai[maxn],bi[maxn];
    int head[maxn],rd[maxn],tot,m,n;
    LL dis[maxn];
    struct Node{
        int id,nxt;
        LL data;
    }edge[maxn];
    void Init()
    {
        tot=1;
        memset(rd,0,sizeof(rd));
        memset(head,-1,sizeof(head));
        memset(dis,INF,sizeof(dis));
    }
    Node tmp;
    void addedge(int x,int y,LL dd)
    {
        tmp.id=y;tmp.data=dd;tmp.nxt=head[x];
        edge[tot]=tmp;
        head[x]=tot++;
        rd[y]++;
    } 
    LL bfs()
    {
        queue <int> q;
        int i,j;
        dis[1]=0;
        for(i=1;i<=n;i++)
        if(rd[i]==0) q.push(i);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(i=head[u];i!=-1;i=edge[i].nxt)
            {
                int v=edge[i].id;
                if(dis[v]>dis[u]+edge[i].data) dis[v]=dis[u]+edge[i].data;
                rd[v]--;
                if(rd[v]==0) q.push(v);
            }
        }
        return dis[n];
    }
    LL MAX(LL x,LL y)
    {
        return x>y?x:y;
    }
    int main(void)
    {
        int T,i,j;
        LL ans;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(i=0;i<m;i++) scanf("%d%d%d%d%d",&u[i],&v[i],&c[i],&ai[i],&bi[i]);
            ans=0;
            Init();
            for(i=0;i<m;i++) addedge(u[i],v[i],(LL)(c[i]-bi[i]));
            ans+=MAX(0ll,bfs());
            
            Init();
            for(i=0;i<m;i++) addedge(u[i],v[i],(LL)(c[i]-ai[i]));
            ans-=MAX(0ll,bfs());
            if(ans>0) printf("cnznb!!!
    %lld
    ",ans);
            else if(ans==0) printf("oof!!!
    ");
            else printf("rip!!!
    %lld
    ",-ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    mysql 5.6
    mysql5.7 二进制包安装
    centos 6 编译安装httpd-2.4
    mysql 5.5源码包安装
    BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
    BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
    BZOJ3435 & 洛谷3920 & UOJ55:[WC2014]紫荆花之恋
    BZOJ5343 & 洛谷4602 & LOJ2555:[CTSC2018]混合果汁——题解
    真·APIO2018滚粗记
    BZOJ4518:[SDOI2016]征途——题解
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10324978.html
Copyright © 2011-2022 走看看