【HDOJ1534】【差分约束+SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1534

Schedule Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2196    Accepted Submission(s): 994
Special Judge

Problem Description

A project can be divided into several parts. Each part should be completed continuously. This means if a part should take 3 days, we should use a continuous 3 days do complete it. There are four types of constrains among these parts which are FAS, FAF, SAF and SAS. A constrain between parts is FAS if the first one should finish after the second one started. FAF is finish after finish. SAF is start after finish, and SAS is start after start. Assume there are enough people involved in the projects, which means we can do any number of parts concurrently. You are to write a program to give a schedule of a given project, which has the shortest time.

Input

The input file consists a sequences of projects.

Each project consists the following lines:

the count number of parts (one line) (0 for end of input)

times should be taken to complete these parts, each time occupies one line

a list of FAS, FAF, SAF or SAS and two part number indicates a constrain of the two parts

a line only contains a ‘#‘ indicates the end of a project

Output

Output should be a list of lines, each line includes a part number and the time it should start. Time should be a non-negative integer, and the start time of first part should be 0. If there is no answer for the problem, you should give a non-line output containing "impossible".

A blank line should appear following the output for each project.

Sample Input

3
2
3
4
SAF 2 1
FAF 3 2
#
3
1
1
1
SAF 2 1
SAF 3 2
SAF 1 3
#
0

Sample Output

Case 1:
1 0
2 2
3 1

Case 2:
impossible

题目大意:给一堆工作所需花费的时间,然后给出工作的顺序【即某些工作要在另一些工作开始之后才能开始,有些工作在另一些工作结束之后才能开始,有些工作在另一些工作结束之后结束,有些工作要在另一些工作开始之后结束..】求怎样安排每个工作的开始时间可以使每件工作尽早结束。

题目分析:定义D【I】表示工作 I 的开始时间,T【I】为 工作 I 的花费时间,则可以根据这些先后顺序列出不等式,然后建图,确保连通,跑一遍SPFA即可

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 using namespace std;
  6 struct edge{
  7     int to;
  8     int next;
  9     int len;
 10 }qwq[100005];
 11 queue<int>pq;
 12 int edge_cnt=0,    n,t[10005],head[100005],in[100005],stk[100005],dist[100005];
 13 bool spfa()
 14 {
 15     while(!pq.empty())
 16     {
 17         pq.pop();
 18     }
 19     pq.push(0);
 20     in[0]++;
 21     stk[0]=1;
 22     while(!pq.empty())
 23     {
 24         int qaq=pq.front();pq.pop();
 25         stk[qaq]=0;
 26         for(int i = head[qaq];i!=-1;i=qwq[i].next)
 27         {
 28             int v=qwq[i].to;
 29             if(dist[v]<dist[qaq]+qwq[i].len)
 30             {
 31                 dist[v]=dist[qaq]+qwq[i].len;
 32                 if(!stk[v])
 33                 {
 34                     pq.push(v);
 35                     in[v]++;
 36                     stk[v]=1;
 37                     if(in[v]>n+1){
 38                         return false;
 39                     }
 40                 }
 41             }
 42         }
 43     }
 44     return true;
 45 }
 46 void add(int x,int y,int z)
 47 {
 48     qwq[edge_cnt].to=y;
 49     qwq[edge_cnt].next=head[x];
 50     qwq[edge_cnt].len=z;
 51     head[x]=edge_cnt++;
 52 }
 53 int main()
 54 {
 55     scanf("%d",&n);
 56     int case1=1;
 57     while(n)
 58     {
 59         memset(head,-1,sizeof(head));
 60         memset(dist,-1,sizeof(dist));
 61         dist[0]=0;
 62         memset(in,0,sizeof(in));
 63         memset(stk,0,sizeof(stk));
 64         edge_cnt=0;
 65         for(int i = 1 ;i <= n ; i++)
 66         {
 67             scanf("%d",&t[i]);
 68         }
 69         char ss[50];
 70         int a,c;
 71         scanf("%s",ss);
 72         while(ss[0]!=‘#‘)//FAS, FAF, SAF and SAS.
 73         {
 74             scanf("%d%d",&a,&c);
 75             if(ss[0]==‘S‘)
 76             {
 77                 if(ss[2]==‘S‘)
 78                 {
 79                     add(c,a,0);
 80                 //    cout << c << a << "0\n";
 81                     //cout << ss[6]<<"   "<<ss[4]-‘0‘ <<  "0" <<endl;
 82                 }
 83                 else
 84                 {
 85                     add(c,a,t[c]);
 86                 //    cout << c << a <<t[c]<<endl;
 87                 //    cout << ss[6]<<"   "<<ss[4]-‘0‘ << t[ss[6]-‘0‘]  <<endl;
 88                 }
 89             }
 90             else
 91             {
 92                 if(ss[2]==‘S‘)
 93                 {
 94                     add(c,a,-t[a]);
 95                     //cout << c << a <<-t[a]<<endl;
 96                 //    cout << ss[6]<<"   "<<ss[4]-‘0‘ << -t[ss[4]-‘0‘]  <<endl;
 97                 }
 98                 else
 99                 {
100                     add(c,a,-t[a]+t[c]);
101                 //    cout << c<<a <<-t[a]+t[c]<<endl;
102                     //cout << ss[6]<<"   "<<ss[4]-‘0‘ << -t[ss[4]-‘0‘]+t[ss[6]-‘0‘] <<endl;
103                 }
104             }
105             for(int i = 1 ; i <= n ; i++)
106             {
107                 add(0,i,0);
108             }
109             scanf("%s",ss);
110         }
111         printf("Case %d:\n",case1++);
112         if(!spfa())
113         printf("impossible\n");
114         else
115         for(int i = 1 ; i <= n ;i++)
116         {
117             printf("%d %d\n",i,dist[i]);
118         }
119         printf("\n");
120         scanf("%d",&n);
121     }
122     return 0;
123  } 

原文地址:https://www.cnblogs.com/MekakuCityActor/p/9028207.html

时间: 2024-11-13 08:40:56

【HDOJ1534】【差分约束+SPFA】的相关文章

POJ 3169 Layout (差分约束+SPFA)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6832   Accepted: 3292 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

ZOJ 2770 Burn the Linked Camp 差分约束+SPFA

第一道正儿八经的差分约束题 有排成一列的n个点,首先告诉你每个点的值最多是多少(最少显然要大于0),然后告诉你m段i,j,k,表示第i个点到第j个点的值的和至少有k,问你总和至少为多少. 要注意的是,告诉你的所有关系式都不要忘记建边,一开始漏了大于0的条件调半天o(╯□╰)o 不等式的形式是a-b<=c这样的= = 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <

【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA

[bzoj2330]: [SCOI2011]糖果 恩..就是裸的差分约束.. x=1 -> (A,B,0) (B,A,0) x=2 -> (A,B,1)  [这个情况加个A==B无解的要特判] x=3 -> (B,A,0)  [恩这个是不少于一开始zz建反了] x=4 -> (B,A,1) x=5 -> (A,B,0) 然后源点到所有点建1的边[恩据说有条链所以要反着连]跑最长路就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #inc

poj3159 差分约束 spfa

1 //Accepted 2692 KB 1282 ms 2 //差分约束 -->最短路 3 //TLE到死,加了输入挂,手写queue 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 using namespace std;

poj3159——Candies(差分约束+SPFA堆栈)

Description During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the kids of flymouse's class a large bag of candies and had flymouse distribute them. All the kids loved candies very much and ofte

(简单) POJ 3169 Layout,差分约束+SPFA。

Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbe

poj3169——Layout(差分约束+SPFA判断负环)

Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbe

BZOJ 2330 [SCOI2011]糖果 差分约束spfa版

题意:自行百度,(之前做过一道candy的升级版). 方法:差分约束 解析:最近在学差分约束什么的,这道是做的第一个bz上的题,感觉还是较简单的.以下我对5种操作进行描述. case 转换不等式 转换不等式2 1 A>=0+B B>=0+A 2 B>=1+A 3 A>=0+B 4 A>=1+B 5 B>=0+A 如上表按照差分约束的原理加边,然后再观察上表不等式方向->为求大边,即最长路. 这些边是不够的,所有人应最少为1糖果,即创出个源点到各点距离为1. 后记:

POJ 3159 Candies(差分约束+spfa+链式前向星)

题目链接:http://poj.org/problem?id=3159 题目大意:给n个人派糖果,给出m组数据,每组数据包含A,B,C三个数,意思是A的糖果数比B少的个数不多于C,即B的糖果数 - A的糖果数<=C . 最后求n 比 1 最多多多少颗糖果. 解题思路:经典差分约束的题目,具体证明看这里<数与图的完美结合——浅析差分约束系统>. 不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值,我们得到 dis[B]-dis[A]<=w(A,B).看到这里,我们可以联想到

HDU 1384 Intervals【差分约束-SPFA】

类型:给出一些形如a−b<=k的不等式(或a−b>=k或a−b<k或a−b>k等),问是否有解[是否有负环]或求差的极值[最短/长路径].例子:b−a<=k1,c−b<=k2,c−a<=k3.将a,b,c转换为节点:k1,k2,k3转换为边权:减数指向被减数,形成一个有向图: 由题可得(b−a) + (c−b) <= k1+k2,c−a<=k1+k2.比较k1+k2与k3,其中较小者就是c−a的最大值.由此我们可以得知求差的最大值,即上限被约束,此时我