首页 > 代码库 > 两个拓扑排序的例题

两个拓扑排序的例题

技术分享

技术分享

技术分享

技术分享

技术分享

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>

using namespace std;

const int MAXN = 6010;
const int MAXM = 5000000;

struct line
{
    int id;
    int x1, y1;
    int x2, y2;
    line(int _id, int _x1, int _y1, int _x2, int _y2):id(_id),x1(_x1),y1(_y1),x2(_x2),y2(_y2) {}
};

struct edge
{
    int v, next;
} e[MAXM];

vector<line> lim;

int p[MAXN], eid;
int indegree[MAXN];

int N;

void init()
{
    memset(p, -1, sizeof(p));
    memset(indegree, 0, sizeof(indegree));
    eid = 0;
}

void insert(int u, int v)
{
    e[eid].v = v;
    e[eid].next = p[u];
    p[u] = eid++;
}

int direction(line a, line b)
{
    if ((a.x1<b.x1 && a.x2<b.x1) || (b.x1<a.x1 && b.x2<a.x1)) return 0;
    if (a.x1==a.x2)
        if(max(a.y1,a.y2)<max(b.y1,b.y2)) return 1;
        else return 2;
    if (b.x1==b.x2)
        if(max(b.y1,b.y2)<max(a.y1,a.y2)) return 2;
        else return 1;
    if (a.x1 <= b.x1)
    {
        if(a.x2 <= b.x2)
        {
            double t=b.y1+1.0*(b.y2-b.y1)*(a.x2-b.x1)/(b.x2-b.x1);
            //cout<<a.id<<" "<<b.id<<"cao"<<a.y2<<" "<<t<<endl;
            if (a.y2 < t) return 1; // a->b
            else return 2; // b->a;
        }
        else
        {
            double t=a.y1+1.0*(a.y2-a.y1)*(b.x2-a.x1)/(a.x2-a.x1);
            if (b.y2 < t) return 2;
            else return 1;
        }
    }
    else
    {
        if(a.x2 <= b.x2)
        {
            double t=b.y1+1.0*(b.y2-b.y1)*(a.x2-b.x1)/(b.x2-b.x1);
            if (a.y2 < t) return 1; // a->b
            else return 2; // b->a;
        }
        else
        {
            double t=a.y1+1.0*(a.y2-a.y1)*(b.x2-a.x1)/(a.x2-a.x1);
            if (b.y2 < t) return 2;
            else return 1;
        }
    }
}

void build()
{
    init();
    int num = lim.size();
    for (int i = 0; i < num-1; i++)
    {
        for (int j = i+1; j < num; j++)
        {int rel = direction(lim[i], lim[j]);
            //printf("%d %d, %d\n", lim[i].id, lim[j].id, rel);
            switch(rel)
            {
            case 0:
                break;
            case 1:
                insert(lim[i].id, lim[j].id);
                indegree[ lim[j].id ]++;
                break;
            case 2:
                insert(lim[j].id, lim[i].id);
                indegree[ lim[i].id ]++;
                break;
            }
        }
    }
}

void topo()
{
    //queue<int> q;
    priority_queue<int> q;
    for (int i = 1; i <= N; i++)
    {
        if (indegree[i] == 0)
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        //int now = q.front();
        int now = q.top();
        printf("%d ", now);
        q.pop();
        for (int i = p[now]; i != -1; i = e[i].next)
        {
            int v = e[i].v;
            indegree[v]--;
            if (!indegree[v])
            {
                q.push(v);
            }
        }
    }
}

int main()
{
    scanf("%d", &N);
    lim.clear();
    for (int i = 0; i < N; i++)
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d", &x1,&y1,&x2,&y2);
        if(x1>x2)
        {
            swap(x1,x2);
            swap(y1,y2);
        }
        lim.push_back(line(i+1,x1,y1,x2,y2));
    }
    build();
    topo();
}

 

技术分享

技术分享

#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>

#define MAXN 10005
#define MAXM 20005
using namespace std;
struct edge
{
    int v,next;
} e[MAXM];
int p[MAXN],eid;
int indegree[MAXN];
int n,m,get_point=0,res;
void init()
{
    memset(p,-1,sizeof(p));
    memset(indegree,0,sizeof(indegree));
    eid=0;
}

void insert(int u,int v)
{
    e[eid].v=v;
    e[eid].next=p[u];
    p[u]=eid++;
    indegree[v]++;
}

int topo()
{
    int ans=0;
    queue<int> q;
    queue<int> cost;

    for(int i=1; i<=n; i++)
    {
        if(!indegree[i])
        {
            q.push(i);
            cost.push(100);
        }
    }

    while(!q.empty())
    {
        get_point++;
        int now=q.front();
        q.pop();
        int co=cost.front();
        cost.pop();
        ans+=co;

        for(int i=p[now]; i!=-1; i=e[i].next)
        {
            int v=e[i].v;
            indegree[v]--;
            if(!indegree[v])
            {
                q.push(v);
                cost.push(co+1);
            }
        }
    }
    return ans;
}

int main()
{
    int a,b;
    scanf("%d%d",&n,&m);
    init();
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&a,&b);
        insert(b,a);
    }
    res=topo();
    if(get_point==n) printf("%d\n",res);
    else printf("Unhappy!\n");
    return 0;
}

 

两个拓扑排序的例题