zoukankan      html  css  js  c++  java
  • P1260 工程规划

    差分约束板子

    差分约束:把 i - j >= x 操作等价于从 j 到 i 连一条边权为 x 的边。然后跑一遍spfa统计最短路,即为一组合法序列。

    这道题里要求以一个点为基准点 0 ,在跑完spfa之后统计最小的dis值,然后按顺序输出dis值减去这个最小值即可。

    另一个问题是图不一定连通,有两个解决方法:

    1.建一个万能点与所有的点相连,当然边权都是0.

    2.跑spfa的时候要记录每个点的弹出次数,因此遍历一遍点,弹出次数为0就spfa,否则continue

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,h[2005]={},dis[2005]={},cnt=0,minn,que[1000500]={},times[2005]={},head,tail;
    bool vis[2005]={};
    struct Edge
    {
        int to,next,w;
    }e[10005];
    void add(int u,int v,int w)
    {
        e[++cnt]=(Edge){v,h[u],w};
        h[u]=cnt;
    }
    void spfa(int st)
    {
        head=0;
        tail=1;
        dis[st]=0;
        que[1]=st;
        times[st]++;
        while(head<tail)
        {
            int u=que[++head];
            vis[u]=0;
            for(int i=h[u];i+1;i=e[i].next)
            {
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].w)
                {
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        times[v]++;
                        if(times[u]>=n) 
                        {
                            printf("NO SOLUTION
    ");
                            exit(0);
                        }
                        que[++tail]=v;
                    }
                }
            }
        }
        vis[st]=0;
    }
    int main()
    {
        memset(h,-1,sizeof(h));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(v,u,w);
        }
        for(int i=1;i<=n;i++)
            dis[i]=214748364;
        for(int i=1;i<=n;i++)
        {
            if(times[i]) 
                continue;
            spfa(i);
        }
            minn=999999999;
            for(int i=1;i<=n;i++) 
                minn=min(minn,dis[i]);
            for(int i=1;i<=n;i++)     
                printf("%d
    ",dis[i]-minn);
        return 0;
    }
  • 相关阅读:
    每周总结
    4月9日学习日志
    4月8日学习日志
    4月7日学习日志
    4月6日学习日志
    Cypress存取时间为10纳秒的异步SRAM
    超低功耗MCU如何降低功耗
    集成铁电存储器MCU为物联网应用提供出色性能
    读取优先和SRAM-MRAM混合结构
    磁阻式随机存储器MRAM基本原理
  • 原文地址:https://www.cnblogs.com/charlesss/p/10534168.html
Copyright © 2011-2022 走看看