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的更多相关文章

  1. vijosP1053 Easy sssp

    vijosP1053 Easy sssp 链接:https://vijos.org/p/1053 [思路] SPFA. 题目中的陷阱比较多,但是只要中规中矩的写SPFA诸如:s与负圈不相连,有重边的情 ...

  2. Easy sssp(spfa)(负环)

    vijos    1053    Easy sssp 方法:用spfa判断是否存在负环 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,00 ...

  3. SPFA_YZOI 1662: Easy sssp

    题目描述 输入数据给出一个有N(2  < =  N  < =  1,000)个节点,M(M  < =  100,000)条边的带权有向图.  要求你写一个程序,  判断这个有向图中是 ...

  4. Vijos1053 Easy sssp[spfa 负环]

    描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...

  5. Loj10086 Easy SSSP

      试题描述 输入数据给出一个有 N 个节点,M 条边的带权有向图.要求你写一个程序,判断这个有向图中是否存在负权回路.如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于 0,就说 ...

  6. vijos 1053 Easy sssp

    描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...

  7. Easy sssp(vijos 1053)

    描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一 ...

  8. Vijos——T1053 Easy sssp

    https://vijos.org/p/1053 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程 ...

  9. Easy sssp(spfa判负环与求最短路)

    #include<bits/stdc++.h> using namespace std; int n,m,s; struct node{ int to,next,w; }e[]; bool ...

随机推荐

  1. POI设置excel某列值为文本格式

    excel单元格格式默认为[常规],当某列限定必须从下拉框选择一个纯数字文本的时候,必须将单元格格式设置为[文本]. 否则即使输入的值和下拉框的一致,excel都认为输入的值是常规类型,而下拉框的值为 ...

  2. window 使用git 非ssh key 面密码登录

    Windows下使用git bash时,总是提示输入用户名密码,严重影响了开发效率,经搜索查找找到了如下有效的解决方案,屡试不爽! 1.先创建存储用户名密码的文件 ,在home文件夹,一般是 C:\D ...

  3. jmeter+ant+jenkins 搭建接口自动化测试

    一.jmeter  我用的jmeter3.2   jmeter要运行,必须本地有java环境,所以需要配置jdk什么的,自行配置 二.ant 安装ant 第一步:下载ant  http://ant.a ...

  4. 如何通过jmeter使用beanshell进行关联

    关联,大多数都是通过响应的信息抓取部分信息,例如session或者hidden等 在jmeter中要使用关联,分为以下2步: Step 1. 在Sampler请求下添加正则表达式,获得信息,添加 &g ...

  5. Phpstorm中使用SFTP

    Phpstorm中经常会出现FTP连接失败的问题,这个时候我们可以使用SFTP来连接服务器. 1.添加服务器.tools--deployment--configuration/browse Remot ...

  6. h5的video标签

    在video标签中,我们可以使用属性:videoWidth & videoHeight,它获取的是video的宽度和高度(媒体本身). 虽然不能直接使用,但是可以通过计算宽高比得到 video ...

  7. java中super关键字

    1.子类的构造函数如果要引用super的话,必须把super放在函数的首位,如果想用super继承父类构造的方法,但是没有放在第一行的话,那么在super之前的语句,肯定是为了满足自己想要完成某些行为 ...

  8. String类的重要方法与字段

    1.Length():获取当前字串长度 2.charAt(int index):获取当前字符串对象下标index处的字符 3.getChars():获取从指定位置起的子串复制到字符数组中 参数:int ...

  9. 安装python虚拟环境

    虚拟环境: 之前安装python包的命令: sudo pip3 install 包名包的安装路径:/usr/local/lib/python3.5/dist-packages安装同一个包的不同版本,后 ...

  10. WPF-TreeView获取文件夹目录、DataGrid获取目录下文件信息

    开发一个WPF桌面应用程序.刚接触WPF编程以及C#语言,这里把一些关键的问题记录下来. 下面是实现将路径的文件夹信息绑定到TreeView及DataGrid上显示. 关键问题是C#数据绑定方式及IE ...