码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1275 Cashier Employment 差分约束

时间:2015-04-18 08:53:47      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:poj   算法   

差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键。

代码:

//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 差分约束

标签:poj   算法   

原文地址:http://blog.csdn.net/sepnine/article/details/45102495

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!