您的位置:首页 > 其它

poj 1275 Cashier Employment 差分约束

2015-04-17 21:40 369 查看
差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键。

代码:

//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;	
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: