zoukankan      html  css  js  c++  java
  • [Luogu] P2859 [USACO06FEB]Stall Reservations S

    (Link)

    Description

    约翰的(N(1<N< 50000))头奶牛实在是太难伺候了,她们甚至有自己独特的产奶时段。当然对于某一头奶牛,她每天的产奶时段是固定的,为时间段(A)(B)(包括时间段(A)和时间段(B))。显然,约翰必须开发一个调控系统来决定每头奶牛应该被安排到哪个牛棚去挤奶,因为奶牛们显然不希望在挤奶时被其它奶牛看见。

    约翰希望你帮他计算一下:如果要满足奶牛们的要求,并且每天每头奶牛都要被挤过奶,至少需要多少牛棚;每头牛应该在哪个牛棚被挤奶。如果有多种答案,你只需任意一种即可。

    Solution

    这个题的贪心思路是很明显的。就是先把时间段按(l)排序,然后不冲突就都安排到一个牛棚,安排完后再开一个新的牛棚。然后找对应牛棚可以建一个有向图,((x,y))表示排完序后(y)(x)后第一个不和它冲突的牛棚,能缩小找的范围。建了图就可以跑深搜了。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n, t, tot, vis[50005], hd[50005], to[50005], nxt[50005], bl[50005];
    
    struct node
    {
    	int l, r, id;
    }p[50005];	
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    void add(int x, int y)
    {
    	tot ++ ;
    	to[tot] = y;
    	nxt[tot] = hd[x];
    	hd[x] = tot;
    	return;
    }
    
    bool operator < (const node &x, const node &y)
    {
    	return x.l < y.l || x.l == y.l && x.r < y.r;
    }
    
    void dfs(int x)
    {
    	vis[p[x].id] = t;
    	for (int i = hd[x]; i; i = nxt[i])
    	{
    		int y = to[i];
    		if (!vis[p[y].id])
    		{
    			dfs(y);
    			return;
    		}
    		else
    		{
    			for (int q = y + 1; q <= n; q ++ )
    			{
    				if (!vis[p[q].id] && p[q].l >= p[x].r + 1)
    				{
    					dfs(q);
    					return;
    				}
    			}
    		}
    	}
    	return;
    }
    
    int main()
    {
    	n = read();
    	for (int i = 1; i <= n; i ++ )
    		p[i].l = read(), p[i].r = read(), p[i].id = i;
    	sort(p + 1, p + n + 1);
    	for (int i = 1; i <= n; i ++ )
    	{
    		int pos = lower_bound(p + 1, p + n + 1, (node){p[i].r + 1, 0}) - p;
    		if (pos != n + 1) add(i, pos);
    	}
    	for (int x = 1; x <= n; x ++ )
    		if (!vis[p[x].id])
    			t ++ , dfs(x);
    	printf("%d
    ", t);
    	for (int i = 1; i <= n; i ++ )
    		printf("%d
    ", vis[i]);
    	return 0;
    }
    
  • 相关阅读:
    Adobe PS
    深入学习二叉树(04)平衡二叉树
    深入学习二叉树(03)二叉查找树
    C 知识点
    实战【docker 镜像制作与使用】
    从0到1了解 CI/CD
    单例模式的几种实现方式,使用场景以及优缺点
    设计模式之策略模式浅谈以及简单例子
    WPF几种渐变色
    Linq学习以及简单用法
  • 原文地址:https://www.cnblogs.com/andysj/p/14027092.html
Copyright © 2011-2022 走看看