HDU 4857 escape (topological sorting + reverse edge construction)

Click here for the title link! ! !
The main idea of ​​the topic:
Give you a few constraints and ask who must be in front of whom. At the same time, the smaller the number is, the more it should be in front. Note that this is not a dictionary order, pay attention to the title description! !
Idea:
First of all, there is no doubt that this basic topological sorting related to priority did not run, but it is obvious that this is not a priority. There are two priority levels, one is the order given by the title (i.e. side), and the other is the numbering order, from small to large. At first I had no idea at all. After reading this very nice blog, I got it! ! ! !
I won't copy him, I will just talk about my understanding. First of all, we all know that if the in-degree of a point is 0, then it must be the highest priority, that is, the starting point. If we think about this problem from the in-degree aspect, we will find that we are not sure to remove that point from the queue first. That is, we cannot determine which point is followed by 1 (or 2 or 3 and so on). So thinking like this is obviously troublesome.
In another direction, since it is a directed graph, if there is no in-degree, it is out-degree. Then think about what the point with a degree of 0 represents, yes, it is the end point. Since we cannot determine the starting point, but we can determine the end point, the problem requires that the front point of the final topological sequence is as small as possible, then the reverse is that the back point is as large as possible And we can also determine the end.
So the overall idea is determined. Consider from the point where the out degree is 0. The general process is as follows:
1. Find all the points with a degree of 0, and put them into the priority queue (Here uses a large root pile, because the following points should be as large as possible)
2. When the queue is not empty, pop the top element of the pile and put the answer end.
3. Traverse all the points connected to it and reduce their out-degree by one. (Because it is necessary to traverse all the points that reach him, not the points he reached, so the problem can be solved by building the reverse side when building the map).
4. When a point with an out-degree of 0 is encountered, the point is put into the priority queue again, and the above process is repeated.
The final result is the answer.

#include<iostream>
#include<queue>
#include<vector>
#include<cstdio>
#include<map>
#include<string>
#include<functional>
#include<algorithm>
#include<cstring>
#define lk (k<<1)
#define rk (k<<1|1)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=3e4+10,M=1e5+10;
int du[N],n,m,ans[N];
struct edge
{
    
    
    int to,next;
}e[M];
int head[N],cnt=0;
void addedge(int u,int v)
{
    
    
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void topsort()
{
    
    
    priority_queue<int>q;
    for(int i=1;i<=n;i++) if(!du[i]) q.push(i);
    int len=n;
    while(!q.empty())
    {
    
    
        int now=q.top();
        q.pop();
        ans[len--]=now;
        for(int i=head[now];i;i=e[i].next)
        {
    
    
            int to=e[i].to;
            du[to]--;
            if(!du[to]) q.push(to);
        }
    }
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        scanf("%d%d",&n,&m);
        memset(head,0,sizeof(head));
        memset(du,0,sizeof(du));
        cnt=0;
        for(int i=1;i<=m;i++)
        {
    
    
            int x,y;
            scanf("%d%d",&x,&y);
            addedge(y,x);
            du[x]++;
        }
        topsort();
        for(int i=1;i<=n;i++)
        {
    
    
            printf("%d",ans[i]);
            if(i!=n) printf(" ");
        }
        printf("\n");
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/amazingee/article/details/107793258