Poj 1275 (差分约束系统)

来源:互联网 发布:ip网络广播系统方案 编辑:程序博客网 时间:2024/05/22 11:32

        这是我的第七道“差分约束系统”,也是最后计划里的最后一道了,也是最难的一道,经过前几道的联系,看到这个题居然还是毫无思路,没办法,只有查资料了,发现这题居然是所谓的黑书——《算法艺术与信息学竞赛》里面的一道原题,这里就不多说了,截张图看一下算了,因为我实在是也不是很彻底地明白其中的道理。哎.....惭愧.....


 

贴代码:

 

/**    第七道差分约束系统    这题比较深奥。。。。。。    详见:《算法艺术与信息学竞赛》**/#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXV 30#define MAXE 1000#define INF  100000000struct{    int  s, e, v;} edge[MAXE];int neg;int dis[MAXV];int r[30], t[30], sum;void add(int s, int e, int v){    edge[neg].s = s;    edge[neg].e = e;    edge[neg].v = v;    neg++;}void change(int s){    int i, j;    neg = 48;    for (j=1; j<=24; j++)    {        i = (j+7)%24 + 1;        if (i > j)            add(i, j, -r[i]);        else            add(i, j, s-r[i]);    }    add(24, 0, -s);}int relax(int s, int e, int v){    if (dis[s]+v < dis[e])    {        dis[e] = dis[s]+v;        return 1;    }    return 0;}int BellmanFord(){    int i, j;    for (i=0; i<=24; i++)        dis[i] = INF;    dis[0] = 0;    for (i=0; i<=24; i++)        for (j=0; j<neg; j++)            relax(edge[j].s, edge[j].e, edge[j].v);    for (j=0; j<neg; j++)        if (relax(edge[j].s, edge[j].e, edge[j].v))            return 0;    return 1;}void Bsearch(int low, int high){    int mid = (low+high)/2;    if (low > high) return ;    change(mid);    if (BellmanFord())    {        sum = mid;        Bsearch(low, mid-1);    }    else        Bsearch(mid+1, high);}int main(){    int  nc, n, k, i;    scanf("%d", &nc);    while (nc--)    {        neg = 0;        memset(t, 0, sizeof(t));        for (i=1; i<=24; i++)            scanf("%d", &r[i]);        scanf("%d", &n);        for (i=0; i<n; i++)        {            scanf("%d", &k);            t[k+1]++;        }        for (i=1; i<=24; i++)        {            add(i-1, i, t[i]);            add(i, i-1, 0);        }        sum = -1;        Bsearch(0, n);        if (sum == -1)            printf("No Solution\n");        else            printf("%d\n", sum);    }}