差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键。
代码:
//poj 1275
//sep9
#include <iostream>
#include <queue>
using namespace std;
const int maxM=10024;
const int maxN=32;
struct Edge
{
int v,w,nxt;
}edge[maxM];
int t[maxN],c[maxN],head[maxN],vis[maxN],inq[maxN],dis[maxN];
int e;
void addedge(int u,int v,int w)
{
edge[e].v=v;edge[e].w=w;edge[e].nxt=head[u];
head[u]=e++;
}
bool spfa()
{
memset(inq,0,sizeof(inq));
for(int i=0;i<=24;++i) dis[i]=INT_MIN;
memset(vis,0,sizeof(vis));
queue<int> Q;
Q.push(0);
dis[0]=0;
inq[0]=1;
vis[0]=1;
while(!Q.empty()){
int u=Q.front();Q.pop();inq[u]=0;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].v,w=edge[i].w;
if(dis[v]<dis[u]+w){
dis[v]=dis[u]+w;
if(inq[v]==0){
Q.push(v);
++vis[v];
inq[v]=1;
if(vis[v]>=25)
return false;
}
}
}
}
return true;
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--){
memset(head,-1,sizeof(head));
memset(t,0,sizeof(t));
for(int i=1;i<=24;++i)
scanf("%d",&c[i]);
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
int x;
scanf("%d",&x);
++t[x+1];
}
int l=0,r=n+1,ans=-1,mid;
while(l<r){
mid=(l+r)/2;
memset(head,-1,sizeof(head));
e=0;
for(int i=0;i<24;++i){
addedge(i,i+1,0);
addedge(i+1,i,-t[i+1]);
}
addedge(0,24,mid);
for(int j=1;j<=24;++j){
int i=j+8;
if(i<=24)
addedge(j,i,c[i]);
else{
i=j+8-24;
addedge(j,i,c[i]-mid);
}
}
if(spfa()){
ans=mid;
r=mid;
}else{
l=mid+1;
}
}
if(ans!=-1)
printf("%d\n",ans);
else
puts("No Solution");
}
return 0;
}
poj 1275 Cashier Employment 差分约束
原文地址:http://blog.csdn.net/sepnine/article/details/45102495