拓扑排序

一、拓扑排序

 1、hdu 1285 确定比赛名次

代码;(领接矩阵 避免 重复)

#include <cstdio>

#include <queue>

#include <vector>

#include <cstring>

#define MAXN 550

using namespace std;

int nVertex, nEdge;

int edge[MAXN][MAXN];

int inDeg[MAXN];

void topOrder(){


    priority_queue<int, vector<int>, greater<int> >que;

    for(int i = 1; i <= nVertex; i++){

        if(inDeg[i] == 0)

            que.push(i);

    }


    int flag = 0;

    while(!que.empty()){


        int front = que.top();

        que.pop();

        if(flag) printf(" ");

        printf("%d", front);

        flag = 1;

        for(int i = 1; i <= nVertex; i++){

            if(edge[front][i] == 0)

                continue;

            inDeg[i] -= edge[front][i];

            if(inDeg[i] == 0)

                que.push(i);

        }

    }

}

int main(){

    while(scanf("%d %d", &nVertex, &nEdge) != EOF){

        memset(edge, 0, sizeof(edge));

        memset(inDeg, 0, sizeof(inDeg));

        for(int i = 0; i < nEdge; i++){

            int a, b;

            scanf("%d %d", &a, &b);


            //重复边多加了 入度 后面会一起 减掉

            edge[a][b]++;

            inDeg[b]++;

        }

        topOrder();

        printf("\n");

    }

    return 0;

}

2、poj 1270 (dfs拓扑排序 输出所有情况 按照字典序大小)

代码:

#include <cstdio>

#include <queue>

#include <vector>

#include <cstring>

#include <iostream>

#define MAXN 550

using namespace std;

/*

a b c

a b c b

*/

int nVertex, nEdge;

int len;

char str[MAXN];

char str2[MAXN];

int nums[MAXN];  //所有字母

vector<int > edges[MAXN];  

int degree[MAXN];

bool vis [MAXN];

vector<int > v;

void Init(){

    v.clear();

    memset(edges,0,sizeof(edges));

    memset(degree,0,sizeof(degree));

}

void dfs(int cnt){


    if(cnt > len) return;


    if(cnt == len){


        for(int i =0;i<len ;i++){


            cout << char(v[i]+'a'-1) <<' ';

        }

        cout << endl;

        return;

    }


    for(int i =0;i<len;i++){


        if(!vis[nums[i]] && !degree[nums[i]]){


            vis[nums[i]] = true;


            for(int j =0;j<edges[nums[i]].size();j++){

                degree[edges[nums[i]][j]]--;

            }


            v.push_back(nums[i]);

            dfs(cnt + 1);

            v.pop_back();


            for(int j =0;j<edges[nums[i]].size();j++){

                degree[edges[nums[i]][j]]++;

            }


            vis[nums[i]] = false;

        }


    }


}

int main(){    


    while(gets(str) != NULL){


        Init();


        int cnt = 0;

        for(int i =0;i<strlen(str);i++){


            if(str[i] <= 'z' && str[i] >= 'a'){


                nums[cnt++] = str[i] - 'a' +1;

            }

        }

        len = cnt;

        gets(str2);

        cnt = 0;

        int pre =0;

        for(int i =0;i<strlen(str2);i++){


            if(str2[i] <= 'z' && str2[i] >= 'a'){


                int now = str2[i] - 'a' +1;


                //录入边关系 加度

                if(cnt == 1) {

                    edges[pre].push_back(now);

                    cnt = 0;

                    degree[now]++;

                    continue;

                }

                if(cnt == 0){

                    pre = now; //前一点下标

                    cnt++;

                }


            }

        }

        dfs(0);

    }


    return 0;

}

3、hdu 3342 Legal or Not(简单 判断有向图 有无环路)

代码:

#include <cstdio>

#include <queue>

#include <vector>

#include <cstring>

#include <iostream>

#include <algorithm>

#define MAXN 550

using namespace std;

/*

3 2

0 1

1 2

2 2

0 1

1 0

0 0

*/

int degree[MAXN];

vector<int > edges[MAXN];

inline int read(){

    int x=0,f=1;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        if(ch=='-')

            f=-1;

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    return x*f;

}

void Init(int n){

    memset(edges,0,sizeof(edges));

    memset(degree,0,sizeof(degree));

}

int main(){    

    int n,m;


    while(1){


        n = read();

        m = read();


        if(n == 0 && m == 0) break;


        Init(n);


        for(int i =1;i<=m;i++){


            int a,b;


            a = read();

            b = read();


            //避免 重复边

            if(find(edges[a].begin(),edges[a].end(),b) == edges[a].end()){


                edges[a].push_back(b);  //输入边关系

                degree[b]++;  //入度加一

            }


        }


        queue<int> q;


        for(int i = 0;i<n;i++){

            if(degree[i] == 0) q.push(i);

        }


        int cnt = 0;

        while(!q.empty()){


            int u = q.front();

            q.pop();

            cnt++;

            for(int i = 0;i<edges[u].size();i++){


                int v = edges[u][i];

                if(--degree[v] == 0) q.push(v);

            }


        }


        if(cnt == n) cout <<"YES"<<endl;

        else cout << "NO" << endl;

    }


    return 0;

}

4、hdu2647 Reward (带权值得 反向建图)

代码:

#include <cstdio>

#include <queue>

#include <vector>

#include <cstring>

#include <iostream>

#include <algorithm>

#define MAXN 10005

using namespace std;

/*

3 2

0 1

1 2

2 2

0 1

1 0

0 0

*/

int w[MAXN];

int degree[MAXN];

vector<int > edges[MAXN];

inline int read(){

    int x=0,f=1;

    char ch=getchar();

    while(ch<'0'||ch>'9'){

        if(ch=='-')

            f=-1;

        ch=getchar();

    }

    while(ch>='0'&&ch<='9'){

        x=(x<<1)+(x<<3)+(ch^48);

        ch=getchar();

    }

    return x*f;

}

void Init(int n){


    memset(w,0,sizeof(w));

    memset(edges,0,sizeof(edges));

    memset(degree,0,sizeof(degree));

}

int main(){    

    int n,m;


    while(scanf("%d %d",&n,&m) != EOF){


        Init(n);


        for(int i =1;i<=m;i++){


            int a,b;


            //反向建图 便于 等下 从最底层 开始 bfs

            b = read();

            a = read();


            //避免 重复边

            if(find(edges[a].begin(),edges[a].end(),b) == edges[a].end()){


                edges[a].push_back(b);  //输入边关系

                degree[b]++;  //入度加一

            }


        }


        queue<int> q;


        for(int i = 1;i<=n;i++){

            if(degree[i] == 0) q.push(i);

        }


        int cnt = 0;

        while(!q.empty()){


            int u = q.front();

            q.pop();

            cnt++;

            for(int i = 0;i<edges[u].size();i++){


                int v = edges[u][i];

                //画图推导这里 向上赋值

                if(--degree[v] == 0) q.push(v),w[v] = w[u]+1;

            }


        }


        long long sum =0;

        if(cnt == n){

            for(int i = 1;i<=n;i++) {


                sum += w[i];

            }

            sum += 888*n;

            cout << sum<< endl;

        }

        else cout << -1 << endl;

    }


    return 0;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 今天学习了字符串,有字符串开头要加#include ,还有字符串的输入gets,输出puts。 以及strcpy(...
    眸若含秋水丶阅读 122评论 0 0
  • 学习了字符串数组, 1. #include #include int main(){ int i; char a[...
    于渤文阅读 49评论 0 0
  • //将原文中的'I'替换成'U' #include #include int main() { char a[20...
    Saltedfish_efd5阅读 100评论 0 0
  • 1.字符串 的简单使用 strcpy strcmp mencpy mencmp //习题 #include #in...
    王子言_853c阅读 217评论 0 0
  • 伊美喜爱的陈皮美食 新会陈皮是广东省江门市新会区的汉族传统名产。当地所产的大红柑的干果皮(也即俗称的陈皮)具有很高...
    e8d3681fa57e阅读 300评论 2 0