Easy sssp
Easy sssp
时间限制: 1 Sec 内存限制: 128 MB
提交: 103 解决:
20
[提交][状态][讨论版]
题目描述
输入数据给出一个有N(2 < = N < = 1,000)个节点,M(M < = 100,000)条边的带权有向图.
要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一个点沿着某条路径出发, 又回到了自己, 而且所经过的边上的权和小于0,
就说这条路是一个负权回路. 如果存在负权回路, 只输出一行-1; 如果不存在负权回路, 再求出一个点S(1 < = S < =
N)到每个点的最短路的长度. 约定: S到S的距离为0, 如果S与这个点不连通, 则输出NoPath.
输入
第一行: 点数N(2 < = N < = 1,000), 边数M(M < = 100,000), 源点S(1
< = S < = N); 以下M行, 每行三个整数a, b, c表示点a, b(1 < = a, b < =
N)之间连有一条边, 权值为c(-1,000,000 < = c < = 1,000,000)
输出
如果存在负权环, 只输出一行-1, 否则按以下格式输出 共N行, 第i行描述S点到点i的最短路: 如果S与i不连通, 输出NoPath;
如果i = S, 输出0; 其他情况输出S到i的最短路的长度.
样例输入
6 8 1
1 3 4
1 2 6
3 4 -7
6 4 2
2 4 5
3 6 3
4 5 1
3 5 4
样例输出
0
6
4
-3
-2
7
提示
做这道题时, 你不必为超时担心, 不必为不会算法担心, 但是如此“简单”的题目, 你究竟能ac么?
题解:这是一道spfa的题目吧,考点是spfa的应用和spfa判断负权回路的问题,每个块都判断一次,若其中有一个块存在负权回路,则直接输出NoPath;如果不存在,则输出最短路即可。
spfa判断负环应该都知道吧,一个点如果进栈n次则存在负环。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<string>
#include<cstring> using namespace std;
const int MAXN=,MAXM=; int num,first[MAXN],next[MAXM],arr[MAXM],cost[MAXM];
int times[MAXN];
int n,m,st;
int p[MAXN];
bool boo[MAXN],he[MAXN];
long long dis[MAXN]; void add(int u,int v,int z)
{
num++;
next[num]=first[u];
first[u]=num;
arr[num]=v;
cost[num]=z;
}
void init()
{
memset(he,,sizeof(he));
memset(times,,sizeof(times));
memset(boo,,sizeof(boo));
memset(next,,sizeof(next));
memset(arr,,sizeof(arr));
memset(cost,,sizeof(cost));
for (int i=;i<=n;i++)
first[i]=-;
num=;
for (int i=;i<=n;i++)
dis[i]=;
dis[st]=;
}
bool pan(int st)
{
int head=,tail=;
p[tail]=st,boo[st]=;
times[st]++; while (head!=tail)
{
head=head%n+;
int u=p[head],v;
for (int i=first[u];i!=-;i=next[i])
{
v=arr[i];
if (dis[u]+cost[i]<dis[v])
{
dis[v]=dis[u]+cost[i];
if (boo[v]==)
{
times[v]++;
if (times[v]>=n)
{
return ;
}
boo[v]=;
tail=tail%n+;
p[tail]=v;
}
}
}
boo[u]=;
}
for (int i=;i<=n;i++)
if (dis[i]<) he[i]=;
return ;
}
void solve(int st)
{
int head=,tail=;
p[tail]=st,boo[st]=; while (head!=tail)
{
head=head%n+;
int u=p[head],v;
for (int i=first[u];i!=-;i=next[i])
{
v=arr[i];
if (dis[u]+cost[i]<dis[v])
{
dis[v]=dis[u]+cost[i];
if (boo[v]==)
{
boo[v]=;
tail=tail%n+;
p[tail]=v;
}
}
}
boo[u]=;
}
for (int i=;i<=n;i++)
if (dis[i]==) printf("NoPath\n");
else printf("%lld\n",dis[i]);
}
int main()
{
scanf("%d%d%d",&n,&m,&st);
init(); int x,y,z;
for (int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for (int i=;i<=n;i++)
if (he[i]==)
{
for (int i=;i<=n;i++)
dis[i]=;
dis[i]=;
if (pan(i))
{
printf("-1\n");
return ;
}
memset(boo,,sizeof(boo));
memset(times,,sizeof(times));
}
for (int i=;i<=n;i++)
dis[i]=;
dis[st]=;
solve(st);
}
Easy sssp的更多相关文章
- vijosP1053 Easy sssp
vijosP1053 Easy sssp 链接:https://vijos.org/p/1053 [思路] SPFA. 题目中的陷阱比较多,但是只要中规中矩的写SPFA诸如:s与负圈不相连,有重边的情 ...
- Easy sssp(spfa)(负环)
vijos 1053 Easy sssp 方法:用spfa判断是否存在负环 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,00 ...
- SPFA_YZOI 1662: Easy sssp
题目描述 输入数据给出一个有N(2 < = N < = 1,000)个节点,M(M < = 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是 ...
- Vijos1053 Easy sssp[spfa 负环]
描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...
- Loj10086 Easy SSSP
试题描述 输入数据给出一个有 N 个节点,M 条边的带权有向图.要求你写一个程序,判断这个有向图中是否存在负权回路.如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于 0,就说 ...
- vijos 1053 Easy sssp
描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...
- Easy sssp(vijos 1053)
描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...
- Vijos——T1053 Easy sssp
https://vijos.org/p/1053 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程 ...
- Easy sssp(spfa判负环与求最短路)
#include<bits/stdc++.h> using namespace std; int n,m,s; struct node{ int to,next,w; }e[]; bool ...
随机推荐
- MySQL(六)之MySQL常用操作符
前言 在前面的MySQL学习中,我们学习了MySQL的安装,管理以及配置,还有是它的DDL.今天给大家分享一下,MySQL的操作符和它的函数这部分. 千里之行始于足下,做什么事情都要脚踏实地的去做才能 ...
- poj3463 最短路和比最短路长1的路径数
这题需要很好的理解Dij. 在Dij的基础上,每个点多一个次短路的长度和数量进行控制. 那么在队列中,最短路控制时出现n次,次短路控制出现n次.注意松弛条件中val值和最短路.次短路的关系. 这题需要 ...
- JQuery实用技巧--学会你也是大神(1)——插件的制作技巧
前 言 JRedu 学习之前,首先我们需要知道什么是JQuery? JQuery是一个优秀的javascript框架. JQuery是继Prototype之后又一个优秀的Javascript框架 ...
- (1)ES6中let,const,对象冻结,跨模块常量,新增的全局对象介绍
1.let声明变量,var声明变量,而const声明的常量 2.let与var的区别 let可以让变量长期驻扎在内存当作 let的作用域是分块[ {快1 {快2 } }每个大括号表示一个独立的块 ...
- 201521123105 第三周Java学习总结
1. 本周学习总结 对象(实际个体) 对象与类 类(模板) 2.书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private ...
- 201521123070《Java程序设计》 第11周学习总结
本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用 ...
- 201521123089 《Java程序设计》第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-21.1 截图你的提交结果(出现 ...
- java课程设计-表达式运算(团队博客)
1 团队课程设计博客 1 团队名称.团队成员介绍 团队名称 奔跑吧土拨鼠 团队成员 洪亚文 201521123065 网络1513 郑晓丽 201521123066 网络1513 2 项目git地址 ...
- Junit4学习(六)Junit4参数化设置
一,背景, 有时候会对相同的代码结构做同样的操作,不同的时对参数的设置数据和预期结果:有没有好的办法提取出来相同的代码,提高代码的可重用度,junit4中使用参数化设置,来处理此种场景: 二,代码展示 ...
- Git 查看/修改用户名、邮箱
用户名和邮箱地址的作用 用户名和邮箱地址是本地Git客户端的一个变量,不随git库而改变. 每次commit都会用用户名和邮箱纪录. github的contributions统计就是按邮箱来统计的. ...