POJ 1275 Cashier Employment(差分约束)

题目链接

详情请看黑书第306页。。。完全根据书做的,我把s[-1]改为s[24]了。

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <cmath>

  4 #include <string>

  5 #include <ctime>

  6 #include <queue>

  7 #include <vector>

  8 using namespace std;

  9 #define INF 10000000

 10 struct node

 11 {

 12     int u,v,w,next;

 13 }edge[100*100];

 14 int first[101],in[101],dis[101],num[101];

 15 int t;

 16 int s[31],r[31],ti[31];

 17 void CL()

 18 {

 19     t = 1;

 20     memset(first,-1,sizeof(first));

 21 }

 22 void add(int u,int v,int w)

 23 {

 24     edge[t].u = u;

 25     edge[t].v = v;

 26     edge[t].w = w;

 27     edge[t].next = first[u];

 28     first[u] = t ++;

 29 }

 30 int spfa()

 31 {

 32     int i,u,v;

 33     for(i = 0;i <= 24;i ++)

 34     {

 35         dis[i] = -INF;

 36         in[i] = 0;

 37         num[i] = 0;

 38     }

 39     queue<int> que;

 40     que.push(24);

 41     in[24] = 1;

 42     dis[24] = 0;

 43     num[24] = 1;

 44     while(!que.empty())

 45     {

 46         u = que.front();

 47         in[u] = 0;

 48         que.pop();

 49         for(i = first[u];i != -1;i = edge[i].next)

 50         {

 51             v = edge[i].v;

 52             if(dis[v] < dis[u] + edge[i].w)

 53             {

 54                 dis[v] = dis[u] + edge[i].w;

 55                 if(!in[v])

 56                 {

 57                     in[v] = 1;

 58                     que.push(v);

 59                     num[v] ++;

 60                     if(num[v] > 24)

 61                     return 1;

 62                 }

 63             }

 64         }

 65     }

 66     return 0;

 67 }

 68 int judge(int mid)

 69 {

 70     CL();

 71     int i,j;

 72     for(i = 1;i <= 23;i ++)

 73     {

 74         add(i-1,i,0);

 75         add(i,i-1,-ti[i]);

 76     }

 77     add(24,0,0);

 78     add(0,24,-ti[0]);

 79     add(24,23,mid);

 80     for(j = 0;j <= 23;j ++)

 81     {

 82         i = (j + 8)%24;

 83         if(i > j)

 84         add(j,i,r[i]);

 85         else

 86         add(j,i,r[i]-mid);

 87     }

 88     if(!spfa()&&dis[23] == mid)

 89     return 1;

 90     else

 91     return 0;

 92 }

 93 int main()

 94 {

 95     int i,j,cas,n,maxz;

 96     scanf("%d",&cas);

 97     while(cas --)

 98     {

 99         maxz = 0;

100         for(i = 0;i < 24;i ++)

101         {

102             scanf("%d",&r[i]);

103             if(maxz < r[i])

104             maxz = r[i];

105         }

106         scanf("%d",&n);

107         for(i = 0;i < n;i ++)

108         {

109             scanf("%d",&j);

110             ti[j] ++;

111         }

112         for(i = 0;i <= n;i ++)

113         {

114             if(judge(i))

115             {

116                 printf("%d\n",i);

117                 break;

118             }

119         }

120         if(i == n+1)

121         printf("No Solution\n");

122     }

123     return 0;

124 }

 

你可能感兴趣的:(差分约束)