做题记录整理贪心2 P3243. [HNOI2015] 菜肴制作(2022/9/9)

[HNOI2015] 菜肴制作

这题是我印象中在初一某次省选同步赛里见到的,当时想怎么会有人做得出这种题(emmm)
与其说是贪心,不如说是构造题
感觉在构造题方面做的太少了
那时候上课的时候旁边一个初二大佬5min想出了正解建返图,然后拓扑(悲)
启示:多做些构造题,多做些拓扑序有关的题

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
using namespace std;
priority_queue<int> q;
struct node{
int to;
int nex;
}a[500005];
struct pp{
	int x;
	int id;
}jl[500005],z;
int hd[500005],cnt;
int sum;
int n,t,x,y,m;
int ans;
int vis[500005],in[500005];
void ru(int x,int y)
{
	a[++cnt].to=y;
	a[cnt].nex=hd[x];
	hd[x]=cnt;
}
bool cmp(pp x,pp y)
{
	return x.x>y.x;
}
int main()
{
	cin>>t;
	while(t--)
	{
		for1(i,1,n) in[i]=0;
		for1(i,1,n) hd[i]=0;
		cnt=0;
		for1(i,1,n) vis[i]=0; 
	    cin>>n>>m;
    	for1(i,1,m)
    	{
    		scanf("%d%d",&x,&y);
    			ru(y,x);
    			in[x]++;
    	}
    	int ji=1;
 		for1(i,1,n) if(in[i]==0) q.push(i);
 		while(!q.empty())
 		{
 			x=q.top();
 			q.pop();
 			if(vis[x]!=0) continue;
 			vis[x]=ji++;
 			for(int i=hd[x];i;i=a[i].nex)
 			{
 				int v=a[i].to;
 				in[v]--;
 				if(in[v]==0)
 				{
 					q.push(v);
 				}
 			}
 		}
 		int kg=0;
 		for1(i,1,n)
 		{
 			if(vis[i]==0)
			 {
			 	kg=1;
			   break;
			}
		 }
		 if(kg==1)
		 {
		 	printf("Impossible! \n");
		 	continue;
		 }
   	   	for(int i=1;i<=n;i++)
 		    	jl[i].x=vis[i],jl[i].id=i;
 		    sort(jl+1,jl+n+1,cmp); 	
 	   	  	for1(i,1,n)
        	printf("%d ",jl[i].id);
 	        printf("\n");
 	}
	
	return 0;
}
posted @ 2022-09-09 20:36  yyx525jia  阅读(21)  评论(0)    收藏  举报