您的位置:首页 > 其它

ZOJ-1455

2014-04-27 14:21 260 查看
继续刷差分约束,其实这类题关键还是找出所有约束条件,算法的话都一样,本题的特殊处在于要加入一个虚拟点表示所有任务全部完成时的点,边长的话就是每个任务所需时间,其他的点则是每个任务的开始时间点,这样除了题目给的那些边外就又加入了N条边,构成了所有约束条件,接下来就是用bellman-ford求最短路了,我看别人用的全是SPFA,效率高一点,但是C的话不好写队列。。只好作罢了

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>

struct Edge
{
int u, v, w;
};
static int d[1024];

static int bellman_ford(struct Edge *array, int n, int total)
{
int i, j, u, v, w, flag;
for (i = 0; i < 1024; i++)
d[i] = INT_MAX;
d[0] = 0;

for (i = 0; i < n; i++)
{
flag = 0;
for (j = 0; j < total; j++)
{
u = array[j].u;
v = array[j].v;
w = array[j].w;
if (d[u] != INT_MAX && d[u] + w < d[v])
{
d[v] = d[u] + w;
flag = 1;
}
}
if (!flag)
break;
}
for (j = 0; j < total; j++)
if (d[array[j].u] != INT_MAX
&& d[array[j].u] + array[j].w < d[array[j].v])
return 0;
return 1;
}

int main()
{
int n, i, time[1024], count = 0;
char s[32], ch[4];
struct Edge *edges = malloc(4096 * sizeof(struct Edge));
while (scanf("%d", &n), n)
{
printf("Case %d:\n", ++count);
int a, b, total = 0;
for (i = 1; i <= n; i++)
{
scanf("%d", &time[i]);
edges[total].u = 0;
edges[total].v = i;
edges[total].w = -time[i];
total++;
}
getchar();
while (gets(s), strcmp(s, "#"))
{
sscanf(s, "%s %d %d", ch, &a, &b);
edges[total].u = a;
edges[total].v = b;
if (strcmp(ch, "FAS") == 0)
edges[total].w = time[a];
else if (strcmp(ch, "FAF") == 0)
edges[total].w = time[a] - time[b];
else if (strcmp(ch, "SAF") == 0)
edges[total].w = -time[b];
else
edges[total].w = 0;
total++;
}
if (bellman_ford(edges, n, total))
{
int min = INT_MAX;
for (i = 1; i <= n; i++)
if (d[i] < min)
min = d[i];
for (i = 1; i <= n; i++)
printf("%d %d\n", i, d[i] - min);
}
else
puts("impossible");
putchar('\n');
}
free(edges);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: