POJ 3342

来源:互联网 发布:邮政网络学员 编辑:程序博客网 时间:2024/06/07 00:09

第一种方法:弗洛伊德最短路

#include <iostream>#include <string>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int Mao[105][105];int main(){    int m,n;    while(cin >> m >> n && m && n)    {        memset(Mao,0,sizeof(Mao));        int x,y;        for(int i=0; i<n; i++)        {            cin >> x >> y;            Mao[x][y]=1;        }        for(int k=0; k<m; k++)            for(int i=0; i<m; i++)                for(int j=0; j<m; j++)                    if(Mao[i][k] && Mao[k][j])                        Mao[i][j]=1;        int flag=0;        for(int i=0; i<m; i++)        {            for(int j=0; j<m; j++)            {                if(Mao[i][j] && Mao[j][i])                {                    flag=1;                    break;                }            }        }        if(flag) cout << "NO" << endl;        else cout << "YES" << endl;    }    return 0;}


第二种方法:DFS拓扑排序

#include <iostream>#include <string>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int G[105][105],topo[105],vis[105];int n,m,t;bool dfs(int u){    vis[u]=-1;//正在访问    for(int v=0;v<n;v++)    {        if(G[u][v])//判断是否存在回路        {            if(vis[v]<0) return false;            else if(!vis[v] && !dfs(v)) return false;//和toposort里面的if一样,存在回路就退出并返回false        }    }    vis[u]=1;//遍历过从u点开始的所有子孙并且未出现回路    topo[--t]=u;//这个可以不要    return true;}bool toposort(){    t=n;    memset(vis,0,sizeof(vis));    for(int u=0;u<n;u++)        if(!vis[u])            if(!dfs(u))                return false;    return true;}int main(){    while(cin >> n >> m && n)    {        int a,b;        memset(G,0,sizeof(G));        for(int i=0;i<m;i++)        {            cin >> a >> b;            G[a][b]=1;        }        if(toposort()) cout << "YES" << endl;        else cout << "NO" << endl;    }    return 0;}

第三个方法:邻接矩阵的拓扑

#include <iostream>#include <string>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int G[105][105];int indegree[105];int n,m,q;bool toposort(){    for(int i=0; i<n; i++)//遍历n遍(共n个点)    {        for(int j=0; j<n; j++)        {            if(!indegree[j])//如果入度为0            {                q++;//记录入度为0的点的个数                indegree[j]--;//改变下入度,不能让其仍然为0,因为后面还会遍历这个点,不改为0以外的值会增加q                for(int k=0; k<n; k++)//删除与入度为0的点和从它出去的边                    if(G[j][k])                        indegree[k]--;//减少与入度为0相连接的点的入度                break;            }        }    }    if(q==n) return true;//删除到不存在入度为零的点,如果一共删除n个,那么不存在回路    else return false;}int main(){    while(cin >> n >> m && n)    {        int a,b;        memset(G,0,sizeof(G));        memset(indegree,0,sizeof(indegree));        q=0;        for(int i=0; i<m; i++)        {            cin >> a >> b;            if(G[a][b]!=1)//很重要,只有这个方法是需要处理重边的情况            {                G[a][b]=1;                indegree[b]++;            }        }        if(toposort()) cout << "YES" << endl;        else cout << "NO" << endl;    }    return 0;}

第四个方法:链式前向星

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 110;const int MAXM = 110;int head[MAXN],queue[MAXN],indegree[MAXN],N,M;struct EdgeNode{    int to;    int w;    int next;};EdgeNode Edges[MAXM];bool toposort(){    int iq = 0;    for(int i = 0; i < N; i++)    {        if(indegree[i] == 0)            queue[iq++] = i;    }    for(int i = 0; i < iq; i++)    {        for(int k = head[queue[i]]; k != -1; k = Edges[k].next)        {            indegree[Edges[k].to]--;            if(indegree[Edges[k].to] == 0)            {                queue[iq++] = Edges[k].to;            }        }    }    if(iq == N)        return true;    return false;}int main(){    int x,y;    while(cin >> N >> M)    {        if(!N && !M)            break;        memset(Edges,0,sizeof(Edges));        memset(head,-1,sizeof(head));        memset(indegree,0,sizeof(indegree));        memset(queue,0,sizeof(queue));        for(int i = 0; i < M; i++)        {            cin >> x >> y;            Edges[i].to = y;            Edges[i].w = 1;            Edges[i].next = head[x];            head[x] = i;            indegree[y]++;        }        if(toposort())            cout << "YES" << endl;        else            cout << "NO" << endl;    }    return 0;}
这个方法也是去删除入度为0的点判断是否存在回路,但是用了链表

引用百度百科原话吧:如果说邻接表是不好写但效率好,邻接矩阵是好写但效率低的话,前向星就是一个相对中庸的数据结构。前向星固然好些,但效率并不高。而在优化为链式前向星后,效率也得到了较大的提升。






原创粉丝点击