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

time:33ms

 #include <cstdio>
#include <cstring>
#define N 3000
using namespace std;
int n, m, T, w[N], u[N], v[N], next[N], first[N], pa[N], d[N], tag, i; void read_graph(void)
{
for(int e = ; e < m; e++)
{
scanf("%d%d%d",&u[e], &v[e], &w[e]);
next[e] = first[u[e]];
first[u[e]] = e;
}
}
void dfs(int x, int fa, int dis)
{
pa[x] = fa;
d[x] = dis;
for(int e = first[x]; e != -; e = next[e])
if(tag) return;
else if(pa[v[e]] == -)//这里应该改为pa[v[e]] != x ,要考虑到负权上的点可能事先被访问过,感谢提出
{
if(v[e] == i && d[x] + w[e] < )
{
puts("possible"), tag = ;
return ;
}
if(v[e] == i)
continue;
dfs(v[e], x, d[x] + w[e]);
}
}
int main(void)
{
scanf("%d", &T);
while(T--)
{
memset(first, -, sizeof(first));
tag = ;
scanf("%d%d", &n, &m);
read_graph();
for(i = ; i < n; i++)
{
memset(d, , sizeof(d)), memset(pa, -, sizeof(pa)),
dfs(i, -, );
if(tag)
break;
}
if(!tag)
puts("not possible");
}
return ;
}

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

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

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

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define INF 0x0f0f0f0f
#define MAXN 1111
#define MAXM 2222
using namespace std; int d[MAXN];
int u[MAXM], v[MAXM], w[MAXM], next[MAXM], first[MAXM];
int t, n, m, e;
void read_graph(void)
{
scanf("%d%d",&n, &m);
for(e = ; e < m; e++)
{
scanf("%d%d%d",&u[e], &v[e], &w[e]);
next[e] = first[u[e]];
first[u[e]] = e;
}
}
void bellman_ford(void)
{
int i;
for(int k = ; k < n-; k++)
for(i = ; i < e; i++ )
{
int x = u[i], y = v[i];
if(d[x] < INF)
d[y] = min(d[y], d[x] + w[i]);
}
for(i = ; i < e; i++)
{
int x = u[i], y = v[i];
if(d[y] > d[x] + w[i])
{
puts("possible");
break;
}
}
if(i == e)
puts("not possible");
}
int main(void)
{
scanf("%d",&t);
while(t--)
{
memset(d, 0x0f, sizeof(d));
memset(first, -, sizeof(first));
d[] = ;
read_graph();
bellman_ford();
}
return ;
}

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

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

 #include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define MAXN 1111
#define MAXM 2222
using namespace std; struct edgeType{
int v, w;
edgeType(int a, int b):v(a), w(b){}
};
int n,m,t;
int time[MAXN], inq[MAXN], d[MAXN]; vector <edgeType> g[MAXN]; bool spfa(void)
{
queue <int> q;
time[] = ;
q.push();
inq[] = ;
while(!q.empty())
{
int x = q.front();
q.pop();
inq[x] = ;
for(int i = ; i < (int)g[x].size(); i++)
if(d[g[x][i].v] > d[x] + g[x][i].w)
{
d[g[x][i].v] = d[x] + g[x][i].w;
time[g[x][i].v]++;
if(time[g[x][i].v] == n + )
return false;
if(!inq[g[x][i].v])
{
q.push(g[x][i].v);
inq[g[x][i].v] = ;
}
}
}
return true;
}
int main(void)
{
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
int a, b, c;
memset(time, , sizeof(time));
memset(inq, ,sizeof(inq));
memset(d, 0x0f,sizeof(d));
d[] = ;
for(int i = ; i < MAXN; i++)
g[i].clear();
for(int i = ; i < m;i++)
{
scanf("%d%d%d", &a, &b, &c);
g[a].push_back(edgeType(b, c));
}
if(spfa())
puts("not possible");
else puts("possible");
}
return ;
}

                                                                 

UVA 558 Wormholes的更多相关文章

  1. uva 558 - Wormholes(Bellman Ford判断负环)

    题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...

  2. UVA 558 Wormholes 【SPFA 判负环】

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  3. UVA - 558 Wormholes (SPEA算法模板题)

    先给出题面:https://vjudge.net/problem/UVA-558 题意描述:给你含n个点以及m条边的图,让你判断在这个图中是否存在负权回路. 首先,我们来介绍什么是SPEA算法 SPF ...

  4. UVA 558 判定负环,spfa模板题

    1.UVA 558 Wormholes 2.总结:第一个spfa,好气的是用next[]数组判定Compilation error,改成nexte[]就过了..难道next还是特殊词吗 题意:科学家, ...

  5. uva 558 tree(不忍吐槽的题目名)——yhx

    You are to determine the value of the leaf node in a given binary tree that is the terminal node of ...

  6. uva 558 Bellman_Ford

    Bellman_Ford算法   求图中是否存在负权值的回路   若图中不存在   则最短路最多经过n-1个结点   若经过超过n-1个节点 则存在负权值的回路  此图永远无法找到最短路  每条边最多 ...

  7. UVA 558 SPFA 判断负环

    这个承认自己没看懂题目,一开始以为题意是形成环路之后走一圈不会产生负值就输出,原来就是判断负环,用SPFA很好用,运用队列,在判断负环的时候,用一个数组专门保存某个点的访问次数,超过了N次即可断定有负 ...

  8. UVA题目分类

    题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...

  9. UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据

    题意:给出几个圆的半径,贴着底下排放在一个长方形里面,求出如何摆放能使长方形底下长度最短. 由于球的个数不会超过8, 所以用全排列一个一个计算底下的长度,然后记录最短就行了. 全排列用next_per ...

随机推荐

  1. UITableViewCell左滑的时候添加多个按钮的方法(iOS8+)以及UIRefreshControl(iOS6+)的使用。

    之前想在cell左滑的时候添加更多的按钮而不是只有‘删除’按钮如下所示,貌似不是一件简单的事.但是现在只要实现几个方法就行了. 代码写的比较垃圾,重在理解这个知识.. . 具体代码: // //  T ...

  2. C# ACM poj1004

    水题.. public static void acm1004(float[] a) { ; foreach (var item in a) { sum += item; } Console.Writ ...

  3. Java多线程同步代码块

    /*多线程的安全问题1.为什么会出现安全问题?因为程序在运行时,会出现一个线程在判断条件满足后,具备了执行资格,但没有运行代码后一个线程也判断了条件,也具备了执行资格,后一个线程运行了代码,但这时候, ...

  4. jsp--文本框正则表达式

    1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace(/\D/g,'')" onafte ...

  5. 2.MySQL入门基本操作初体验

    启动和关闭mysql服务器: 一.启动方式 1.使用 mysqld 脚本启动:/etc/inint.d/mysqld start 2.使用 守护进程safe_mysqld 启动:safe_mysqld ...

  6. 【nodemailer】 初试

    nodemailer 是什么? 简单的讲nodemailer就是用来发送邮件的.最近的一个项目需要向客户的注册邮箱发送验证连接,研究了一下. 刚开始我以为nodemailer还可以用来接收邮件,看了好 ...

  7. c#个人记录常用方法(更新中)

    1.日期毫秒转换为标准的C#日期格式 //使用时,先将秒Convert.ToInt64,返回格式2015-2-10 14:03:33 public DateTime JavaTimeToC(long ...

  8. svg学习笔记(一)

    SVG——可扩展适量图形,基于XML PC端:IE9+   wap端:表现良好,适合使用 基础图形: line(线段)  <line x1="25" y1="150 ...

  9. [HTML] <input> 标签

      可选的属性 属性 值 描述 accept mime_type 规定通过文件上传来提交的文件的类型. align left right top middle bottom 不赞成使用.规定图像输入的 ...

  10. python中 “与,或,异或”

    在python编程语言里面: 按位的运算,都按位的运算,都是把参加运算的数的二进制形式进行运算. 1.与运算:A与B值均为1时,A.B与的运算结果才为1,否则为0 (运算符:&) 2.或运算: ...