• Schedule Problem spfa 差分约束


      

    题意:有n个任务,给出完成n个任务所需时间,以及一些任务安排。任务安排有四种:

    FAS a b:任务a需在任务b开始后完成。

    FAF a b:任务a需在任务b完成后完成。

    SAF a b:任务a需在任务b完成后开始。

    SAS a b:任务a需在任务b开始后开始。

    求在这些任务安排下各个任务的最早开始时间,若任务安排为不可能安排则输出impossible。每组数据结束需要输出一个空行。

    思路:四种任务安排可以得到四种不等式如下:(dis[]表示任务开始时间,x[]表示任务完成所需时间)

    FAS a b:dis[a]+x[a]>=dis[b]

    FAF a b:dis[a]+x[a]>=dis[b]+x[b]

    SAF a b:dis[a]>=dis[b]+x[b]

    SAS a b:dis[a]>=dis[b]

    因为求任务开始的最早时间即最小值,加上此题有好多的不等式可以进行差分约束。所以建图,spfa()最长路即可求得答案。

    终于看到一个比较不那么抽象的差分约束了

    记得连上超级源点0

    显然不可能有短路

    当有环的时候没有答案!

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f
    #define N 100000
    int head[N];
    int pos;
    struct node
    {
        int to,v,nex;
    }edge[10000000];
    void add(int a,int b,int c)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].v=c;
        edge[pos].to=b;
    }
    int n;
    
    int vis[N],dis[N],cnt[N];
    bool spfa()
    {
        rep(i,1,n)
        vis[i]=0,dis[i]=-inf,cnt[i]=0;
        dis[0]=0;
        vis[0]=1;
        cnt[0]++;
        queue<int>q;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=head[u];i;i=edge[i].nex)
            {
                int v=edge[i].to;
                if(dis[v]<dis[u]+edge[i].v)
                {
                    dis[v]=dis[u]+edge[i].v;
                    if(!vis[v])
                    {
                        if(++cnt[v]>n)return 0;
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return 1;
    }
    int t[N];
    int main()
    {
        int cas=0;
        while(RI(n),n)
        {
            printf("Case %d:
    ",++cas);
            CLR(head,0);
            pos=0;
            rep(i,1,n)RI(t[i]);
    
            int a,b;
            char s[5];
            while(1)
            {
                RS(s);
                if(s[0]=='#')break;
                RII(a,b);
                if(s[0]=='F')
                {
                    if(s[2]=='S')
                        add(b,a,-t[a]);
                    else
                        add(b,a,t[b]-t[a]);
                }
                else
                {
                    if(s[2]=='F')
                        add(b,a,t[b]);
                    else
                        add(b,a,0);
                }
            }
            rep(i,1,n)
            add(0,i,0);
            
            if(spfa())
            {
                rep(i,1,n)
                printf("%d %d
    ",i,dis[i]);
            }
            else
            printf("impossible
    ");
            cout<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C# DataGridView搜索
    C# DataGridView插入DB
    C# 扩展类
    C# Clone控件
    C# 动态事件示例
    C# 遍历控件 示例
    c的详细学习(11)文件
    c的详细学习(10)结构体与共用体的学习(二)
    c的详细学习(9)结构体与共用体的学习(一)
    c的详细学习(8)指针学习(二)
  • 原文地址:https://www.cnblogs.com/bxd123/p/10780752.html
Copyright © 2020-2023  润新知