JZOJ 1621. 【Usaco2009 gold 】头晕的奶牛【图论借用】

目录:


题目:

单击看题目


分析:

这道题主要考察的是我们将图转化为线性结构,我们可以考虑到拓扑排序,这样一来,这道题就变得十分简单了
先跑一边拓扑排序,记录序号,然后按排序后序号的大小定向


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct edg{
    int x,y,next;
}e[100001];//邻接表
queue<int>q;
int d[100001],l[100001],t[100001],m,c;
void add(int x,int y)
{
    e[++m]=(edg){x,y,l[x]};
    l[x]=m;
}
void topsort()//拓扑排序
{
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=l[now];i;i=e[i].next)
        {
            if(!(--d[e[i].y]))
            {
                q.push(e[i].y);
                t[e[i].y]=++c;
            }
        }
    }
    return;
}
int main()
{    
//    freopen("dizzy.in","r",stdin);
//    freopen("dizzy.out","w",stdout);
    int n=read(),m1=read(),m2=read();
    int x,y;
    m=0;
    for(int i=1;i<=m1;i++)
    {
        x=read();y=read();
        add(x,y);//构建单向边
        d[y]++;
    }
    for(int i=1;i<=n;i++)
      if(!d[i])
      {
        q.push(i);
        t[i]=++c;
      }
    topsort();
    for(int i=1;i<=m2;i++)
    {
        x=read();y=read();
        if(t[x]<t[y]) printf("%d %d\n",x,y);//由小指向大,即不会形成环
        else printf("%d %d\n",y,x);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/80961577