• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 联系
  • 订阅
  • 管理

View Post

poj 1275 Cashier Employment 差分约束

        这题的不等式比较难列,列了很久,也列不全,对那个8小时理解的不透。

        设num[i] 为来应聘的在第i个小时开始工作的人数

           r[i] 为第i个小时至少需要的人数

           x[i] 为招到的在第i个小时开始工作的人数

       根据题意有:

         0 <= x[i] <= num[i]

         x[i] + x[i-1] + …+ x[i-7] >= r[i] (题目中的连续工作8小时)

      再设 s[i] = x[1] + … + x[i]

      则有: s[i] – s[i-1] >= 0

                    s[i-1] – s[i] >= –num[i]

                    s[i] – s[i-8] >= r[i], 8 <= i <= 24

                    s[i] – s[i+16] >= r[i] – s[24],  1<= i <= 7

      还需要添加一个隐藏不等式: s[24] – s[0] >= ans(枚举的答案)

      通过枚举s[24],来检测是否满足条件,题目是求最小值,即求最长路,以0为源点。

 

#include <iostream>
#include <queue>
using namespace std;

const int N = 30;
const int MAX = 10000;
const int INF = 1000000000;

struct Node
{
	int v;
	int cost;
	int next;
};

Node node[MAX];
queue<int> Q;
int adj[N];
int num[N];
int size;
int r[N];
int s[N];
int cnt[N];
bool in_q[N];

void add_edge(int u, int v, int cost)
{
	node[size].v = v;
	node[size].cost = cost;
	node[size].next = adj[u];
	adj[u] = size++;
}

bool spfa(int ans)
{
	for (int i = 0; i <= 24; i++)
	{
		s[i] = -INF;
		cnt[i] = 0;
		in_q[i] = false;
	}

	while (!Q.empty()) Q.pop();

	int u, v, w;
	s[0] = 0;
	Q.push(0);
	in_q[0] = true;

	while (!Q.empty())
	{
		u = Q.front();
		Q.pop();
		in_q[u] = false;

		for (int i = adj[u]; i != -1; i = node[i].next)
		{
			v = node[i].v;
			w = node[i].cost;

			if (s[v] < s[u] + w)
			{
				s[v] = s[u] + w;

				if (!in_q[v])
				{
					in_q[v] = true;
					Q.push(v);
					if (++cnt[v] > 24)
						return false;
				}
			}
		}
	}
	if (s[24] == ans)
		return true;
	else
		return false;
}
int main()
{
	int cases;
	int n, c;
	bool has_solution;

	cin >> cases;

	while (cases--)
	{
		for (int i = 1; i <= 24; i++)
		{
			scanf("%d", &r[i]);
			num[i] = 0;
		}

		cin >> n;
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &c);
			num[c+1]++;
		}
		int ans;
		
		for ( ans = 0; ans <= n; ans++)
		{
		    size = 0;
			has_solution = false;
			for (int i = 0; i <= 24; i++)
				adj[i] = -1;

			for (int i = 1; i <= 24; i++)
			{
				add_edge(i-1, i, 0);
				add_edge(i, i-1, -num[i]);

				if (i >= 8)
					add_edge(i-8, i, r[i]);
			}

			for (int i = 1; i <= 7; i++)
				add_edge(i+16, i, r[i]- ans);

			add_edge(0, 24, ans);

			if (spfa(ans))
			{
				has_solution = true;
				break;
			}

		}

		if (has_solution)
			printf("%d\n", ans);
		else
			printf("No Solution\n");
	}
	return 0;
}

posted on 2011-01-26 21:09  sysuwhj  阅读(555)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3