Luogu P3243 [HNOI2015] cuisine making

Keywords: Programming less

Title gate

This problem seems to know that it is a topological sort. In addition, it should be a legal solution to find the smallest dictionary order, so greedy to find the point with the smallest number with the current entry degree of 0.

Congratulations, you fell into a hole.

In fact, I did this at the beginning. Later, when I blew up the third group of data in the sample test, this group of data can be used to block this greedy (such an example is really conscience).

Let's consider the opposite. The maximum value (set to xxx) of the last placement method is obviously the best, because it can make the number less than xxx move forward, while the number greater than xxx has no effect anywhere because the position of xxx has been determined. After filling in the last digit, consider the second to last and the third to last Finally, when we get to the first place, we will find that the reverse order of the answers is the sequence with the largest dictionary order, so we can build the reverse graph, and then greedily find the topological sequence with the largest dictionary order, and then reverse the output.

Paste code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=100010;
struct node
{
    int cnt,id;
    friend bool operator<(const node &x,const node &y)
	{ if(x.cnt==y.cnt)return x.id<y.id;return x.cnt>y.cnt;}
	//Overloaded operators because structs are used 
}a[N];
int t,m,n,top,ans[N],h[N],pre[N],to[N];
bool vis[N];
priority_queue<node>q;
void ins(int u,int v)
{
    pre[++top]=h[u];h[u]=top;to[top]=v;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);ans[0]=top=0;bool f=true;
        memset(vis,false,sizeof(vis));memset(h,0,sizeof(h));
        while(!q.empty())q.pop();
        for(int i=1;i<=n;i++)a[i].cnt=0,a[i].id=i;//Initialize some arrays and priority queues to use 
        while(m--)
        {
            int x,y;scanf("%d%d",&x,&y);
            ins(y,x);a[x].cnt++;//Reverse edge building, statistical penetration 
        }
        for(int i=1;i<=n;i++)q.push(a[i]);
        while(!q.empty())
        {
            int x=q.top().id;q.pop();
            if(vis[x])continue;
            if(a[x].cnt>0){ f=false;break;}
			//If the entry of the point with the lowest entry is greater than 0, there is no solution 
            vis[x]=true;ans[++ans[0]]=x;
            for(int i=h[x];i;i=pre[i])
            {
                int v=to[i];
                a[v].cnt--;q.push(a[v]);
            }
        }
        if(!f)printf("Impossible!\n");
        else
        {
            for(int i=n;i>1;i--)printf("%d ",ans[i]);
            printf("%d\n",ans[1]);
        }//Reverse output 
    }
    return 0;
}

Posted by jboku on Tue, 10 Dec 2019 17:08:06 -0800