拓扑排序入门

来源:互联网 发布:tomcat连接池配置优化 编辑:程序博客网 时间:2024/06/08 05:10

输入:

先输入n,m表示点数,边数

然后输入有向边 u  v(从u指向v)

输出:

如果有环输出Network has a cycle!

没有环就输出拓扑序列

输入样例:

6 8
1 2
1 4
2 6
3 2
3 6
5 1
5 2
5 6
6 8
1 3
1 2
2 5
3 4
4 2
4 6
5 4
5 6
0 0
输出样例:

5 1 4 3 2 6

Network has a cycle!


题解:

使用邻接链表存边

使用拓扑算法进行拓扑排序:

先找到所有的入度为0的点入栈

然后删除栈顶元素,以及这个点相应的边(这个点加入输出序列中)

删除边后如果有入度为0的点就加入栈(重复第二步)


注意:如果栈里面没有数据了并且图中的点并没有完全处理完,那么就存在环

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAXN 10000#define mem(a) memset(a,0,sizeof(a))struct Node{    int to;    Node* next;};int n,m;///顶点个数,边数Node* List[MAXN];///邻接表表头指针int counts[MAXN];///各顶点的度数char output[1000];///输出内容int pos=0;///output数组的指针void topo_sort(){    int top=-1;    Node* temp;    bool flag=0;    for(int i=0;i<n;i++)///入度为0开始入栈        if(counts[i]==0)            counts[i]=top,top=i;    for(int i=0;i<n;i++){        if(top==-1){            flag=true;break;        }        int j=top;        top=counts[top];///顶点J入栈        pos+=sprintf(output+pos,"%d ",j+1);/*sprintf函数函数功能:把格式化的数据写入某个字符串函数原型:int sprintf( char *buffer, const char *format [, argument] … );返回值:字符串长度(strlen)*/        temp=List[j];        while(temp)        {            int k=temp->to;            if(--counts[k]==0)                counts[k]=top,top=k;            temp=temp->next;        }    }    if(flag)        puts("Network has a cycle!\n");    else{        int len=strlen(output);        output[len-1]=0;        puts(output);    }}int main(){    int u,v;    freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m),n&&m)    {        mem(List),mem(counts),mem(output);//-------------建立邻接---------------------//        Node* temp;        for(int i=0;i<m;i++){            scanf("%d%d",&u,&v);            u--,v--;            counts[v]++;            temp=new Node;            temp->to=v,temp->next=NULL;            if(List[u]==NULL)                List[u]=temp;            else{                temp->next=List[u];                List[u]=temp;            }        }//-------------------------------------------//        topo_sort();//--------------释放内存---------------------//        for(int i=0;i<n;i++){            temp=List[i];            while(temp)            {                List[i]=temp->next;                delete temp;                temp=List[i];            }        }    }    return 0;}


0 0
原创粉丝点击