• 洛谷 P1938 [USACO09NOV] 找工就业Job Hunt


    这道题可以说是一个复活SPFA的题

    因为数据比较小,SPFA也比较简单

    那就复习(复读)一次SPFA吧

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    
    using namespace std;
    
    int bj=0;
    struct edge{
        int next,to,dis;
    };
    int d[1020];
    int head[2500];
    int dm,p,c,f,s;
    int rd[1120];
    edge e[4000];
    int vis[4000];
    int size;
    int mmx=-1;
    
    void spfa(int x)  //本题n(c),m(p+s)极小,因此SPFA在最坏复杂度下O(mn)也不会炸 
    {
        queue <int> q;
        q.push(x);
        vis[s]=1;//SPFA易忘操作,标记这个点是否在队中,如果不标记可能会出现死循环 
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            if(rd[t]>=2*(c+p+f)) //当出现环的时候一般取一个点入队(n+m)次优化效率,为了防止毒瘤出题人*了2 
            {
                bj=1;
                break;
            }
            vis[t]=0;
            int i,j,k;
            for(i=head[t];i;i=e[i].next)
            {
                j=e[i].to;
                k=e[i].dis;
                if(d[t]-k+dm>d[j])  //至于不能取d[t]-k+d[j]>d[j]的原因是有可能d[j]包含了d[t] 
                {
                    d[j]=d[t]-k+dm;
                    rd[j]++;
                    if(vis[j]) continue;
                    vis[j]=1;
                    q.push(j);
                }
            }
        }
    }
    void addedge(int next,int to,int dis)
    {
        e[++size].next=head[next];
        e[size].to=to;
        e[size].dis=dis;
        head[next]=size;
    }
    int main()
    {
        scanf("%d %d %d %d %d",&dm,&p,&c,&f,&s);
        int i,j;
        for(i=1;i<=p;i++)
        {
            int t1,t2;
            scanf("%d %d",&t1,&t2);
            addedge(t1,t2,0);  //题上说了没有花费 
        }    
        for(i=1;i<=c;i++) d[i]=dm;
        for(i=1;i<=f;i++)
        {
            int t1,t2,t3;
            scanf("%d %d %d",&t1,&t2,&t3);
            addedge(t1,t2,t3);
        }
        spfa(j);
        if(bj==1) //如果出现环 
        {
            printf("-1 
    ");
            return 0;
        }
        if(!bj)  //如果没有 
        {
            for(i=1;i<=c;i++)
            mmx=max(d[i],mmx);
        }    
        printf("%d",mmx);
        return 0;
    }
  • 相关阅读:
    新功能:查看TrackBack过来的文章
    新功能发布: 数据备份
    小题大作:.Text中恶意脚本过滤的新方法
    新增关闭邮件通知功能
    Will Mono Become the Preferred Platform for Linux Development
    Test Driven Development 资源
    收藏夹注意事项
    功能调整:阅读排行、回复排行
    首页增加了到第二书店的链接
    DotGNU Portable.NET
  • 原文地址:https://www.cnblogs.com/zsx6/p/11061389.html
Copyright © 2020-2023  润新知