UVA-10305Ordering Tasks ——拓補排序(DFS實現、隊列實現)

Ordering Tasks

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;

int n,m,a[105][105],ans[105],cnt;
bool v[105];
void dfs(int u)
{
    for(int y=1;y<=n;y++)
    {
        if(a[u][y] && !v[y]) dfs(y);
    }
    v[u]=1;
    ans[cnt--]=u;
}

void topological()
{
    for(int i=1;i<=n;i++)
    {
        if(!v[i]) dfs(i);
    }
}


int main(){
    while (~scanf("%d%d",&n,&m) && (n||m)) {
        ms0(a);ms0(v);ms0(ans);cnt=n;
        for(int i =1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x][y]=1;
        }
        topological();
        for(int i=1;i<n;i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

完整的可以判斷環的版本(來自紫書)。

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
#define EPS  1e-10
#define ms0(a) memset(a,0,sizeof(a))
using namespace std;


int m,n,c[110],G[110][110],topo[110],cnt;
bool dfs(int x){
    c[x] = -1; //表明x節點正在遞歸的棧幀中
    for(int y=1;y<=n;y++){
        if(G[x][y]){
            if(c[y]==-1){
                return false;
            }
            if(c[y]==0 && !dfs(y)){
                return false;
            }
        }
    }
    c[x] = 1;
    topo[cnt--] = x;
    return true;
}
bool topoSort(){
    cnt = n;
    for(int x=1;x<=n;x++){
        if(!c[x]){
            if(!dfs(x)) {
                return false;
            }
        }
    }
    return true;
}


int main(){
    while(scanf("%d%d",&n,&m) && (n || m)){
        ms0(G);
        ms0(topo);
        ms0(c);
        for(int i=0;i<m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            G[x][y] = 1;
        }
        topoSort();
        for(int i=1;i<=n-1;i++) {
            printf("%d ",topo[i]);
        }
        printf("%d\n",topo[n]);
    }
    return 0;
}

如果用入度的思想,並藉助隊列實現,可能更加直觀。

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
#define EPS  1e-10
#define ms0(a) memset(a,0,sizeof(a))
using namespace std;


int m,n,inDegree[110];
vector<int> G[110];
vector<int> ans;

bool topoSort(){
    queue<int> q;
    for(int i=1;i<=n;i++){
        if(inDegree[i]==0){
            q.push(i);
        }
    }
    while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int y:G[x]){
            if(--inDegree[y]==0){
                q.push(y);
            }
        }
        ans.push_back(x);
    }
    return ans.size()==n;
}

int main(){
    while(scanf("%d%d",&n,&m ) && (m||n) ){
        ms0(inDegree);
        ms0(G);
        ans.clear();
        for(int i=0;i<m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            inDegree[y]++;
        }
        topoSort();
        for(int i=0;i<ans.size()-1;i++){
            printf("%d ",ans[i]);
        }
        printf("%d\n",ans[ans.size()-1]);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章