首页 > 其他分享 >poj 1691

poj 1691

时间:2023-05-29 22:36:21浏览次数:43  
标签:xl int indegree ans poj 1691 xr rec


题目大意:

墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色。为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色。但是如果两块区域颜色不同就要换涂颜色用的刷子。问最少需要换几次。


解题思路:由于这题有一个限制条件,即上方的所有区域都已经涂好颜色,所以肯定是要求一个满足条件的拓扑序列,既然这样就很好办了,把上下两个相邻的矩形建立一条由上到下的有向边,然后dfs去搜索满足条件的拓扑序列。

AC:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int inf = 0x3f3f3f;
struct node
{
	int xl,yl,xr,yr;
	int c;
}rec[20];
struct Edge
{
	int k,next;
}edge[50];
int n,cnt,pre[50],indegree[50],ans;
bool vis[20];

bool cmp(node a,node b)
{
	return a.yl < b.yl;
}

void addedge(int u,int v)
{
	edge[cnt].k = v;
	edge[cnt].next = pre[u];
	pre[u] = cnt++;
}

void dfs(int cur,int tmp,int dep)
{
	if(dep == n)	//所有点都找到
	{
		if(tmp < ans) ans = tmp;
		return;
	}
	if(tmp >= ans) return;   //当前的解大于已知最优解
	for(int i = pre[cur]; i != -1; i = edge[i].next)
	{
		int k = edge[i].k;
		indegree[k]--;
	}
	for(int i = 1; i <= n; i++)
	{
		if(vis[i] == true) continue;
		if(indegree[i] == 0)
		{
			vis[i] = true;
			if(rec[i].c != rec[cur].c)
				dfs(i,tmp+1,dep+1);
			else dfs(i,tmp,dep+1);
			vis[i] = false;
		}
	}
	for(int i = pre[cur]; i != -1; i = edge[i].next)	//把修改的入度恢复原状
	{
		int k = edge[i].k;
		indegree[k]++;
	}
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(pre,-1,sizeof(pre));
		memset(vis,false,sizeof(vis));
		memset(indegree,0,sizeof(indegree));
		cnt = 0;
		scanf("%d",&n);
		for(int i = 1; i <= n; i++)
			scanf("%d%d%d%d%d",&rec[i].yl,&rec[i].xl,&rec[i].yr,&rec[i].xr,&rec[i].c);
		sort(rec+1,rec+1+n,cmp);
		for(int i = 1; i <= n; i++)
			for(int j = i + 1; j <= n; j++)
			{
				if(rec[i].yr != rec[j].yl) continue;
				if(rec[i].xl >= rec[j].xl && rec[i].xr <= rec[j].xr)
				{
					addedge(i,j);
					indegree[j]++;
				}
				else if(rec[i].xl <= rec[j].xl && rec[i].xr >= rec[j].xr)
				{
					addedge(i,j);
					indegree[j]++;
				}
				else if(rec[i].xl < rec[j].xr && rec[i].xl > rec[j].xl)
				{
					addedge(i,j);
					indegree[j]++;
				}
				else if(rec[i].xr < rec[j].xr && rec[i].xr > rec[j].xl)
				{
					addedge(i,j);
					indegree[j]++;
				}
			}
		ans = inf;
		for(int i = 1; i <= n; i++)
			if(indegree[i] == 0)
			{
				vis[i] = true;
				dfs(i,1,1);
				vis[i] = false;
			}
		printf("%d\n",ans);
	}
	return 0;
}




标签:xl,int,indegree,ans,poj,1691,xr,rec
From: https://blog.51cto.com/u_16143128/6374314

相关文章

  • poj 1201(差分约束)
    IntervalsTimeLimit: 2000MS MemoryLimit: 65536KTotalSubmissions: 23934 Accepted: 9075DescriptionYouaregivennclosed,integerintervals[ai,bi]andnintegersc1,...,cn. Writeaprogramthat: readsthenumberofintervals,the......
  • poj 1716(贪心)
    题意:给出数轴上的n个区间,每个区间都是连续的int区间。现在要在数轴上任意取一堆元素,构成一个元素集合V,要求每个区间和元素集合V的交集至少有两个不同的元素求集合V最小的元素个数。解题思路:考虑到区间之间的重叠性,所以每次都要尽可能地去每个区间靠后的值,才能保证前后两个区间公共......
  • poj 2362(剪枝)
    题意:给定一堆不定长度的小棒子,问他们能否构成一个正方形。解题思路:最开始写的时候把题意弄错了,以为只要能够从中取出一部分构成矩形即可。。。。这里注意一下几个剪枝的地方:1)要把所有的棒子都用上且组成正方形,那么sum%4=0;2)如果棒子长度小于4,肯定是不行的3)如果棒子中有长度大于s......
  • poj 1988(并查集)
    题意:进行m次操作,M x y 将包含x的集合移动到y上面,C x, 计算x下面有几个元素。解题思路:这道题很容易想到用并查集,但是这里有点绕;最开始我想到的是建立一个num[x],表示x以下的节点数,但这样会有一个问题,要更新num[x]时,必须要枚举哪些节点的父节点为p,由于节点数太多,所以TLE是难免的......
  • poj 1230(贪心)
    解题思路:这道题目是用贪心的思想,从左向右扫描场地的每一列是否合法。若不合法,贪心的找出从该列起向右延伸最长的m道墙,移除这m道墙使得该列合法。我最开始代码会出现这样的问题:如果两个墙是连在一起的,那么会被当做一个墙来处理。。。AC:#include<iostream>#include<cstdio>#inclu......
  • poj 1634
    题意:一个员工A的直接上司是那些薪水大于A,并且身高>=A的人中薪水最少的一个。主席CEO的薪水最高,且身高也是最高的。有多组数据。每组数据给出m个员工,和q个询问。每个员工有id、薪水、身高。对于每个询问,给出某个id,让你求该员工的直接上司的id和该员工的下属的个数。若该员工......
  • poj 1451(Trie)
    题意:就是让你模拟手机输入单词。具体就是给你一些单词,以及该单词被使用的频数,这个频数也是该单词前缀的使用频数,当然不同的单词有可能有相同的前缀,那么这个相同的前缀的使用频数就是这两个单词使用频数之和,以此类推。然后再给你一些数字串,让你针对该数字串的每一个前缀输出它的最有......
  • poj 1190(剪枝)
    生日蛋糕TimeLimit: 1000MS MemoryLimit: 10000KTotalSubmissions: 16191 Accepted: 5751Description7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri,高度为Hi的圆......
  • poj 3281(最大流)
    解题思路:这是道匹配的问题,最近刚学网络流,所以想用网络流去做。。按照题目要求,我开始建立的是food----cow----drink的图,源点与所有的food的编号连接,所有的drink的编号与汇点连接,这里所有的有向边的容量都为1,。。但很不幸的是WA了。。看了别人的思路,我才知道原来这里保证不了一头牛......
  • poj 1935(搜索+回溯)
    解题思路:先我们考虑从源点出发到所有自己想要经过的点然后在回到源点sum,显然每条边都必须经过源点(这个我们可以一次dfs求出),但题目的意思是可以不用回到源点,那么我们可以再求源点到所有要经过的点的最远距离ans,于是答案便是sum-ans.这道题的思路确实是很巧妙,一开始我还是在想如......