zoukankan      html  css  js  c++  java
  • 拓扑排序

    以下是关于拓扑排序应用的例题

     1 #include <iostream>
     2 #include <vector>
     3 #include <queue>
     4 #include <cstring>
     5 using namespace std;
     6 const int maxn = 1e5 + 10;
     7 int T, n, m, u, v, num;
     8 int InDeg[maxn];//入度 
     9 vector<int> vec[maxn];//邻接表 
    10 //判断是否有环 
    11 queue<int> q; 
    12 //复杂度0(v + e) 
    13 /*
    14 2
    15 2 2
    16 1 2
    17 2 1
    18 3 2
    19 1 2
    20 1 3
    21 输出 Wrong
    22 Correct 
    23 */
    24 bool topsort(){
    25     while(!q.empty()){//清空队列 
    26         q.pop();
    27     }
    28     int num=0;//记录被删去的节点数 
    29     for(int i = 1; i <= n; i++){
    30         if(!InDeg[i]){//将入度为0的顶点入队 
    31             q.push(i);
    32         }
    33     }
    34     while(!q.empty()){
    35         int now = q.front();
    36         q.pop();
    37         num++;
    38         //遍历当前元素下一个元素的所有元素 
    39         for(int i= 0;i < vec[now].size();i++){
    40             //与当前点连的,入度为1的入队(且减为0)度数大于1的度数减1但不入队,小于1的不影响 
    41             if(--InDeg[vec[now][i]] == 0){
    42                 q.push(vec[now][i]);
    43             }
    44         }
    45     }
    46     //若删去的点等于原来图中点的个数则该有向图无环 
    47     if(num == n) return true;
    48     return false;
    49 }
    50 int main(){
    51     scanf("%d", &T);
    52     while(T--){
    53         scanf("%d%d", &n, &m);//读入n个顶点m条边 
    54         for(int i = 1; i <= n; i++){//清空该顶点到其他顶点的边 
    55             vec[i].clear();
    56         }
    57         memset(InDeg, 0, sizeof(InDeg)); //将记录入度的数组清空 
    58         while(m--){//读入m条边 
    59             scanf("%d%d", &u,&v);
    60             vec[u].push_back(v);//从u到v建立连接(有向图) 
    61             InDeg[v]++;//将v的入度加1 
    62         }
    63         if(topsort()){
    64             puts("Correct");
    65         }else{
    66             puts("Wrong");
    67         } 
    68     }
    69     return 0;
    70 } 

    拓扑排序二

    #1175 : 拓扑排序·二

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒。这事在校内BBS上立刻引起了大家的讨论,当然小Hi和小Ho也参与到了其中。从大家各自了解的情况中,小Hi和小Ho整理得到了以下的信息:

    • 校园网主干是由N个节点(编号1..N)组成,这些节点之间有一些单向的网路连接。若存在一条网路连接(u,v)链接了节点u和节点v,则节点u可以向节点v发送信息,但是节点v不能通过该链接向节点u发送信息。
    • 在刚感染病毒时,校园网立刻切断了一些网络链接,恰好使得剩下网络连接不存在环,避免了节点被反复感染。也就是说从节点i扩散出的病毒,一定不会再回到节点i。
    • 当1个病毒感染了节点后,它并不会检查这个节点是否被感染,而是直接将自身的拷贝向所有邻居节点发送,它自身则会留在当前节点。所以一个节点有可能存在多个病毒。
    • 现在已经知道黑客在一开始在K个节点上分别投放了一个病毒。

    举个例子,假设切断部分网络连接后学校网络如下图所示,由4个节点和4条链接构成。最开始只有节点1上有病毒。

    最开始节点1向节点2和节点3传送了病毒,自身留有1个病毒:

    其中一个病毒到达节点2后,向节点3传送了一个病毒。另一个到达节点3的病毒向节点4发送自己的拷贝:

    当从节点2传送到节点3的病毒到达之后,该病毒又发送了一份自己的拷贝向节点4。此时节点3上留有2个病毒:

    最后每个节点上的病毒为:

    小Hi和小Ho根据目前的情况发现一段时间之后,所有的节点病毒数量一定不会再发生变化。那么对于整个网络来说,最后会有多少个病毒呢?

    提示:拓扑排序的应用

    输入

    第1行:3个整数N,M,K,1≤K≤N≤100,000,1≤M≤500,000

    第2行:K个整数A[i],A[i]表示黑客在节点A[i]上放了1个病毒。1≤A[i]≤N

    第3..M+2行:每行2个整数 u,v,表示存在一条从节点u到节点v的网络链接。数据保证为无环图。1≤u,v≤N

    输出

    第1行:1个整数,表示最后整个网络的病毒数量 MOD 142857

    样例输入
    4 4 1
    1
    1 2
    1 3
    2 3
    3 4
    样例输出
    6


     1 #include <iostream>
     2 #include <vector>
     3 #include <queue>
     4 #include <cstring>
     5 using namespace std;
     6 const int maxn = 1e5 + 10;
     7 const int mod = 142857;
     8 int T, n, m, u, v;
     9 int InDeg[maxn];//入度 
    10 int virus[maxn];//病毒的数量 
    11 vector<int> vec[maxn];//邻接表 
    12 queue<int> q; 
    13 //拓扑排序二 
    14 void topsort(){
    15     while(!q.empty()){//清空队列 
    16         q.pop();
    17     }
    18     for(int i = 1; i <= n; i++){
    19         if(!InDeg[i]){//将入度为0的顶点入队 
    20             q.push(i);
    21         }
    22     }
    23     while(!q.empty()){
    24         int now = q.front();
    25         q.pop();
    26         //遍历当前元素下一个元素的所有元素 
    27         for(int i= 0;i < vec[now].size();i++){
    28             //与当前点连的,入度为1的入队(且减为0)度数大于1的度数减1但不入队,小于1的不影响 
    29             if(--InDeg[vec[now][i]] == 0){
    30                 q.push(vec[now][i]);
    31             }
    32             //与当前元素相连的元素的病毒数=(当前元素的病毒数+ 当前元素相连的元素的病毒数) % mod 
    33             virus[vec[now][i]] = (virus[vec[now][i]] + virus[now]) % mod;
    34         }
    35     }
    36     
    37 }
    38 int main(){
    39     int k, x;
    40     while(~scanf("%d%d%d",&n,&m,&k)){
    41         for(int i = 1; i <= n; i++){//清空该顶点到其他顶点的边 
    42             vec[i].clear();
    43         }
    44         memset(InDeg, 0, sizeof(InDeg)); //将记录入度的数组清空 
    45         memset(virus, 0, sizeof(virus)); 
    46         while(k--){
    47             scanf("%d",&x);
    48             virus[x]++;
    49         }
    50         while(m--){//读入m条边 
    51             scanf("%d%d", &u,&v);
    52             vec[u].push_back(v);//从u到v建立连接(有向图) 
    53             InDeg[v]++;//将v的入度加1 
    54         }
    55         topsort();
    56         int ans = 0; 
    57         for(int i = 1; i <= n; i++){
    58             ans = (ans + virus[i]) % mod;
    59         }
    60         printf("%d
    ",ans);
    61     }
    62     return 0;
    63 } 

    In this winter holiday, Bob has a plan for skiing at the mountain resort.

    This ski resort has MM different ski paths and NNdifferent flags situated at those turning points.

    The ii-th path from the S_iSi-th flag to the T_iTi-th flag has length L_iLi.

    Each path must follow the principal of reduction of heights and the start point must be higher than the end point strictly.

    An available ski trail would start from a flag, passing through several flags along the paths, and end at another flag.

    Now, you should help Bob find the longest available ski trail in the ski resort.

    Input Format

    The first line contains an integer TT, indicating that there are TT cases.

    In each test case, the first line contains two integers NN and MM where 0 < N leq 100000<N10000and 0 < M leq 1000000<M100000 as described above.

    Each of the following MM lines contains three integers S_iSiT_iTi, and L_i~(0 < L_i < 1000)Li (0<Li<1000)describing a path in the ski resort.

    Output Format

    For each test case, ouput one integer representing the length of the longest ski trail.

    样例输入

    1
    5 4
    1 3 3
    2 3 4
    3 4 1
    3 5 2

    样例输出

    6

     1 #include <iostream>
     2 #include <vector>
     3 #include <queue> 
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 const int maxn = 1e5 + 10;
     8 //pair中的first为终点second为边的权值,vec的下标为起点 
     9 vector<pair<int, int> > vec[maxn];//邻接表 
    10 int InDeg[maxn], dp[maxn];//InDeg用来记录每个点的入度,dp用来记录从起点到当前点的最长路 
    11 queue<int> q;
    12 int T,n,m,k,u,v,w,x,ans;
    13 void topsort(){
    14     while(!q.empty()){
    15         q.pop();
    16     }
    17     for(int i = 1; i <= n; i++){
    18         if(!InDeg[i]) q.push(i);
    19     }
    20     while(!q.empty()){
    21         int now = q.front();
    22         q.pop();
    23         for(int i = 0; i < vec[now].size(); i++){
    24             if(--InDeg[vec[now][i].first] == 0){
    25                 q.push(vec[now][i].first);
    26             }
    27             dp[vec[now][i].first] = max(dp[vec[now][i].first],dp[now] + vec[now][i].second);
    28         }
    29     }
    30 }
    31 int main(){
    32     scanf("%d", &T);
    33     while(T--){
    34         scanf("%d%d", &n, &m);
    35         for(int i = 1; i <= n; i++){
    36             vec[i].clear();
    37         }
    38         memset(InDeg, 0, sizeof(InDeg));
    39         memset(dp, 0, sizeof(dp));
    40         while(m--){
    41             scanf("%d%d%d", &u,&v,&w);
    42             vec[u].push_back(make_pair(v, w));
    43             InDeg[v]++;
    44         }
    45         topsort();
    46         int maxx = -1;
    47         for(int i = 1; i <= n; i++){
    48             maxx = max(maxx, dp[i]);
    49         }
    50         printf("%d
    ", maxx);
    51     }
    52     return 0;
    53 }
    D. Almost Acyclic Graph
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given a directed graph consisting of n vertices and m edges (each edge is directed, so it can be traversed in only one direction). You are allowed to remove at most one edge from it.

    Can you make this graph acyclic by removing at most one edge from it? A directed graph is called acyclic iff it doesn't contain any cycle (a non-empty path that starts and ends in the same vertex).

    Input

    The first line contains two integers n and m (2 ≤ n ≤ 500, 1 ≤ m ≤ min(n(n - 1), 100000)) — the number of vertices and the number of edges, respectively.

    Then m lines follow. Each line contains two integers u and v denoting a directed edge going from vertex u to vertex v (1 ≤ u, v ≤ nu ≠ v). Each ordered pair (u, v) is listed at most once (there is at most one directed edge from u to v).

    Output

    If it is possible to make this graph acyclic by removing at most one edge, print YES. Otherwise, print NO.

    Examples
    input
    Copy
    3 4
    1 2
    2 3
    3 2
    3 1
    output
    Copy
    YES
    input
    Copy
    5 6
    1 2
    2 3
    3 2
    3 1
    2 1
    4 5
    output
    Copy
    NO
    Note

    In the first example you can remove edge , and the graph becomes acyclic.

    In the second example you have to remove at least two edges (for example,  and ) in order to make the graph acyclic.



    这道题代码先放在这里,抽时间分析
     1 #include <iostream>
     2 #include <queue>
     3 #include <vector>
     4 #include <cstring>
     5 using namespace std;
     6 const int maxn = 1e5 + 10;
     7 vector<int> vec[maxn];
     8 int inDeg[maxn], ruDeg[maxn], flag;
     9 int ans, T, n, m, u, v, sorted;
    10 queue<int> q;
    11 bool topsort(){
    12     while(!q.empty()){
    13         q.pop();
    14     }
    15     sorted = 0;
    16     for(int i = 1; i <= n; i++){
    17         if(inDeg[i] == 0){
    18             q.push(i);
    19         }
    20     }
    21     while(!q.empty()){
    22         int now = q.front();
    23         q.pop();
    24         ++sorted;
    25         for(int i = 0; i < vec[now].size(); i++){
    26             if(--inDeg[vec[now][i]] == 0){
    27                 q.push(vec[now][i]);
    28             }
    29         }
    30     }
    31     if(sorted == n){
    32         return true;
    33     }
    34     return false;
    35 }
    36 int main(){
    37     while(~scanf("%d%d",&n,&m)){
    38         for(int i = 1; i <= n; i++){
    39             vec[i].clear();
    40         }
    41         memset(inDeg, 0, sizeof(inDeg));
    42         memset(ruDeg, 0, sizeof(ruDeg));
    43         sorted = 0;
    44         while(m--){
    45             scanf("%d%d",&u,&v);
    46             vec[u].push_back(v);
    47             ruDeg[v]++;
    48             inDeg[v]++;
    49         }
    50         if(topsort()){
    51             puts("YES");
    52             continue;
    53         }else{
    54             flag = 0;
    55             for(int i = 1; i <= n; i++){
    56                 memcpy(inDeg, ruDeg, sizeof(ruDeg));
    57                 if(inDeg[i] >= 1){
    58                     inDeg[i]--;
    59                     if(topsort()){
    60                         flag = 1;
    61                         puts("YES");
    62                         break;
    63                     }
    64                 }
    65             }
    66         }
    67         if(flag == 0){
    68             puts("NO");
    69         }
    70     }
    71     return 0;
    72 } 
  • 相关阅读:
    Python格式符号
    Python基础知识
    HDFS 数据流程
    HDFS IO流操作
    HDFS API操作
    Hadoop 客户端环境准备
    Hadop 环境搭建 windows10+hadoop2.7.7
    Hadoop HDFS shell
    Hadoop HDFS 基础
    centos 更改清华源
  • 原文地址:https://www.cnblogs.com/AGoodDay/p/10745072.html
Copyright © 2011-2022 走看看