zoukankan      html  css  js  c++  java
  • 判断DAG图

    拓扑排序O(E), bellman O(VE)   , 使用邻接表的dfs O(V+E) ,floyd O(N*N*N)

    bellman算法只能判断是否存在负环。

    所以可以先把权值全部设为-1

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <stack>
     5 using namespace std;
     6 const int N = 10000 + 10;
     7 const int INF = 1<<30;
     8 struct node
     9 {
    10     int u,v,weight;
    11 }g[N+N];
    12 int dist[N];
    13 inline int max(const int &a, const int &b)
    14 {
    15     return a < b ? b : a;
    16 }
    17 
    18 void init(int n)
    19 {
    20     for(int i=0; i<=n; ++i)
    21     {
    22     
    23         dist[i] = INF;
    24     }
    25 }
    26 
    27 void relax(int u, int v, int weight)
    28 {
    29     if(dist[v]  > dist[u] + weight)
    30         dist[v] = dist[u] + weight;    
    31 }
    32 bool bell(int n, int m)
    33 {
    34     int i,j;
    35     for(i=1; i<n; ++i)
    36         for(j=0; j<m; ++j)
    37             relax(g[j].u,g[j].v,g[j].weight);
    38     
    39     for(i=0; i<m; ++i)
    40         if(dist[g[i].v] > dist[g[i].u] +g[i].weight)
    41             return true;
    42     return false;
    43 }
    44 int main()
    45 {
    46     int n,m,i,u,v;
    47     while(scanf("%d%d",&n,&m)!=EOF)
    48     {
    49         if(n==0 && m==0)
    50             break;
    51         init(n);
    52         for(i=0; i<m; ++i)
    53         {
    54             scanf("%d%d",&g[i].u,&g[i].v);
    55             g[i].weight = -1;//把权值全部改为负的,然后判断是不是存在负环
    56             if(g[i].u==0)
    57                 dist[g[i].v] = -1;
    58         }
    59         if(bell(n,m))
    60             puts("NO");
    61         else
    62             puts("YES");
    63     }
    64 }
    View Code

    枚举起点进行dfs,如果能遇到顶点和起点相同,则存在环

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <stack>
     5 using namespace std;
     6 const int N = 10000 + 10;
     7 vector<int> g[N];
     8 int start;
     9 bool vis[N],flag;
    10 void dfs(int u)
    11 {
    12     if(flag)
    13         return;
    14     for(int i=0;i<g[u].size(); ++i)
    15     {
    16         int v = g[u][i];
    17         if(v==start)
    18         {
    19             flag = true;//有环
    20             return;
    21         }
    22         if(!vis[v])
    23         {
    24             vis[v] = true;
    25             dfs(v);
    26         }
    27     }
    28 }
    29 int main()
    30 {
    31     int n,m,i,u,v;
    32     while(scanf("%d%d",&n,&m)!=EOF)
    33     {
    34         if(n==0 && m==0)
    35             break;
    36         for(i=0; i<n; ++i)
    37             g[i].clear();
    38         for(i=0; i<m; ++i)
    39         {
    40             scanf("%d%d",&u,&v);
    41             g[u].push_back(v);
    42         }
    43         flag = false;
    44         for(i=0; i<n; ++i)
    45         {
    46             memset(vis,0,sizeof(vis));
    47             vis[i] = true;
    48             start = i;
    49             dfs(i);
    50             if(flag)
    51                 break;
    52         }
    53         if(flag)
    54             puts("NO");
    55         else
    56             puts("YES");
    57     }
    58 }
    View Code

    拓扑排序如果能生成n个顶点序列,那么说明是GAG图

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <stack>
     5 using namespace std;
     6 const int N = 10000 + 10;
     7 vector<int> g[N];
     8 stack<int> st;
     9 int in[N],add[N],cnt;
    10 inline int max(const int &a, const int &b)
    11 {
    12     return a < b ? b : a;
    13 }
    14 void topSort(int n, int m)
    15 {    
    16     int u,i;
    17     for(i=1; i<=n; ++i)
    18         if(in[i]==0)
    19             st.push(i);
    20     while(!st.empty())
    21     {
    22         u = st.top();
    23         cnt++;
    24         st.pop();
    25         for(i=0; i<g[u].size(); ++i)
    26         {
    27             --in[g[u][i]];
    28             if(in[g[u][i]]==0)
    29                 st.push(g[u][i]);
    30         
    31                 
    32         }
    33     }
    34 }
    35 void init(int n)
    36 {
    37     cnt = 0;
    38     for(int i=1; i<=n; ++i)
    39     {
    40         g[i].clear();
    41         add[i] = in[i] = 0;
    42     }
    43 }
    44 int main()
    45 {
    46     int n,m,i,u,v;
    47     while(scanf("%d%d",&n,&m)!=EOF)
    48     {
    49         if(n==0 && m==0)
    50             break;
    51         init(n);
    52         for(i=0; i<m; ++i)
    53         {
    54             scanf("%d%d",&u,&v);
    55             u++;
    56             v++;
    57             g[u].push_back(v);
    58             in[v]++;
    59         }
    60         topSort(n,m);
    61         if(cnt==n)//能生成n个顶点的序列,说明是DAG图
    62         {
    63             puts("YES");
    64         }
    65         else
    66             puts("NO");
    67     }
    68 }
    View Code
  • 相关阅读:
    SpringDataJpa实体类常用注解
    I2C子系统
    input子系统
    platform深入
    运用层是怎样找到驱动的+open中子设备识别
    misc设备
    文章标题
    uboot2015第一阶段---SPL
    git工具使用
    Andriod底层第五课------HAL硬件抽象层
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4342599.html
Copyright © 2011-2022 走看看