zoukankan      html  css  js  c++  java
  • UVA 558 Wormholes

    要问是否存在一个总权重为负数的环,用dfs即可解决。

     time:33ms

     1 #include <cstdio>
     2 #include <cstring>
     3 #define N 3000
     4 using namespace std;
     5 int n, m, T, w[N], u[N], v[N], next[N], first[N], pa[N], d[N], tag, i;
     6 
     7 void read_graph(void)
     8 {
     9     for(int e = 0; e < m; e++)
    10     {
    11         scanf("%d%d%d",&u[e], &v[e], &w[e]);
    12         next[e] = first[u[e]];
    13         first[u[e]] = e;
    14     }
    15 }
    16 void dfs(int x, int fa, int dis)
    17 {
    18     pa[x] = fa;
    19     d[x] = dis;
    20     for(int e = first[x]; e != -1; e = next[e])
    21         if(tag) return;
    22         else if(pa[v[e]] == -1)//这里应该改为pa[v[e]] != x ,要考虑到负权上的点可能事先被访问过,感谢提出 
    23         {
    24             if(v[e] == i && d[x] + w[e] <  0)
    25             {
    26                 puts("possible"), tag = 1;
    27                 return ;
    28             }
    29             if(v[e] == i)
    30                 continue;
    31             dfs(v[e], x, d[x] + w[e]);
    32         }
    33 }
    34 int main(void)
    35 {
    36     scanf("%d", &T);
    37     while(T--)
    38     {
    39         memset(first, -1, sizeof(first));
    40         tag = 0;
    41         scanf("%d%d", &n, &m);
    42         read_graph();
    43         for(i = 0; i < n; i++)
    44         {
    45             memset(d, 0, sizeof(d)), memset(pa, -1, sizeof(pa)),
    46                    dfs(i, -1, 0);
    47                    if(tag)
    48                     break;
    49         }
    50         if(!tag)
    51             puts("not possible");
    52     }
    53     return 0;
    54 }

     或者采用bellman—ford算法判断负权回路,

    第n次循环时,若d[y]>d[x] + w[i],也就是能够继续松弛下去说明图中存在负权回路。

    time:44ms速度还慢了一点,相比dfs

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #define INF 0x0f0f0f0f
     6 #define MAXN 1111
     7 #define MAXM 2222
     8 using namespace std;
     9 
    10 int d[MAXN];
    11 int u[MAXM], v[MAXM], w[MAXM], next[MAXM], first[MAXM];
    12 int t, n, m, e;
    13 void read_graph(void)
    14 {
    15     scanf("%d%d",&n, &m);
    16     for(e = 0; e < m; e++)
    17     {
    18         scanf("%d%d%d",&u[e], &v[e], &w[e]);
    19         next[e] = first[u[e]];
    20         first[u[e]] = e;
    21     }
    22 }
    23 void bellman_ford(void)
    24 {
    25     int i;
    26     for(int k = 0; k < n-1; k++)
    27         for(i = 0; i < e; i++ )
    28     {
    29         int x = u[i], y = v[i];
    30         if(d[x] < INF)
    31             d[y] = min(d[y], d[x] + w[i]);
    32     }
    33     for(i = 0; i < e; i++)
    34     {
    35         int x = u[i], y = v[i];
    36         if(d[y] > d[x] + w[i])
    37         {
    38             puts("possible");
    39             break;
    40         }
    41     }
    42     if(i == e)
    43         puts("not possible");
    44 }
    45 int main(void)
    46 {
    47     scanf("%d",&t);
    48     while(t--)
    49     {
    50         memset(d, 0x0f, sizeof(d));
    51         memset(first, -1, sizeof(first));
    52         d[0] = 0;
    53         read_graph();
    54         bellman_ford();
    55     }
    56     return 0;
    57 }

     然后是spfa算法求解是否存在负权回路,通过判断顶点出队次数大于顶点数n,可知存在负权路,源点的time[0]应该初始化为1,其他的点每松弛一次,次数增加。

    time:77ms竟然比bellman—ford,自己写的dfs倒是成了最快的了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #include <vector>
     5 #define MAXN 1111
     6 #define MAXM 2222
     7 using namespace std;
     8 
     9 struct edgeType{
    10 int v, w;
    11 edgeType(int a, int b):v(a), w(b){}
    12 };
    13 int n,m,t;
    14 int time[MAXN], inq[MAXN], d[MAXN];
    15 
    16 vector <edgeType> g[MAXN];
    17 
    18 bool spfa(void)
    19 {
    20     queue <int> q;
    21     time[0] = 1;
    22     q.push(0);
    23     inq[0] = 1;
    24     while(!q.empty())
    25     {
    26         int x = q.front();
    27         q.pop();
    28         inq[x] = 0;
    29         for(int i = 0; i < (int)g[x].size(); i++)
    30             if(d[g[x][i].v] > d[x] + g[x][i].w)
    31             {
    32                 d[g[x][i].v] = d[x] + g[x][i].w;
    33                 time[g[x][i].v]++;
    34                 if(time[g[x][i].v] == n + 1)
    35                     return false;
    36                 if(!inq[g[x][i].v])
    37                 {
    38                     q.push(g[x][i].v);
    39                     inq[g[x][i].v] = 1;
    40                 }
    41             }
    42     }
    43     return true;
    44 }
    45 int main(void)
    46 {
    47     scanf("%d", &t);
    48     while(t--)
    49     {
    50         scanf("%d%d", &n, &m);
    51         int a, b, c;
    52         memset(time, 0, sizeof(time));
    53         memset(inq, 0,sizeof(inq));
    54         memset(d, 0x0f,sizeof(d));
    55         d[0] = 0;
    56          for(int i = 0; i < MAXN; i++)
    57             g[i].clear();
    58         for(int i = 0; i < m;i++)
    59         {
    60             scanf("%d%d%d", &a, &b, &c);
    61             g[a].push_back(edgeType(b, c));
    62         }
    63         if(spfa())
    64             puts("not possible");
    65         else puts("possible");
    66     }
    67     return 0;
    68 }

                                                                     

  • 相关阅读:
    几何画板绘制三棱锥的教程
    MathType给公式底部加箭头的教程
    几何画板有哪些快捷键可以用
    公式编辑器调整公式边框粗细的教程
    wdcp安装
    搭建git for windows服务器(100%可以成功)
    百度echarts
    简单的js菜单
    真正的让iframe自适应高度 兼容多种浏览器随着窗口大小改变
    Hadoop学习笔记(一)从官网下载安装包
  • 原文地址:https://www.cnblogs.com/rootial/p/3297994.html
Copyright © 2011-2022 走看看