您的位置:首页 > 其它

P3385 【模板】负环

2017-11-09 20:24 99 查看

 P3385 【模板】负环

题目描述

暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索

输入输出格式

输入格式:

 

第一行一个正整数T表示数据组数,对于每组数据:

第一行两个正整数N M,表示图有N个顶点,M条边

接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)

 

输出格式:

 

共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。

 

输入输出样例

输入样例#1: 复制
2
3 4
1 2 2
1 3 4
2 3 1
3 1 -3
3 3
1 2 3
2 3 4
3 1 -8
输出样例#1: 复制
N0
YE5

说明

N,M,|w|≤200 000;1≤a,b≤N;T≤10 建议复制输出格式中的字符串。

此题普通Bellman-Ford或BFS-SPFA会TLE

 

code

 

#include<cstdio>
#include<cstring>

const int N = 500100;
struct Edge{
int to,nxt,w;
}e
;
int head
,tot,n,m,dis
;
bool vis
;

inline int read() {
int x = 0,f = 1;char ch = getchar();
for (; ch<'0'||ch>'9'; ch = getchar())
if (ch=='-') f = -1;
for (; ch>='0'&&ch<='9'; ch = getchar())
x = x*10+ch-'0';
return x*f;
}
inline void add_edge(int u,int v,int w) {
e[++tot].to = v,e[tot].nxt = head[u],e[tot].w = w,head[u] = tot;
}
bool spfa(int u) {
vis[u] = true;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to,w = e[i].w;
if (dis[v] > dis[u]+w) {
if (vis[v]) return true;
dis[v] = dis[u]+w;
if (spfa(v)) return true;
}
}
vis[u] = false;
return false;
}
int main() {

int T = read();
while (T--) {
memset(head,0,sizeof(head));
memset(dis,0x3f,sizeof(dis)); // 可以是0
memset(vis,false,sizeof(vis));
tot = 0;
n = read(),m = read();
for (int u,v,w,i=1; i<=m; ++i) {
u = read(),v = read(),w = read();
if (w < 0) add_edge(u,v,w);
else add_edge(u,v,w),add_edge(v,u,w);
}
bool flag = false;
for (int i=1; i<=n; ++i)
if (spfa(i)) {flag = true;break;}
if (flag) puts("YE5");
else puts("N0");
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: