您的位置:首页 > 其它

洛谷—— P3385 【模板】负环

2017-05-20 18:03 471 查看

https://www.luogu.org/problem/show?pid=3385#sub

题目描述

暴力枚举/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

 

不能用百分数,就用电风扇~~~

 

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int N(200000+5);
int t,n,m,u,v,w;
int sumedge,head
;
struct Edge
{
int to,next,cost;
Edge(int to=0,int next=0,int cost=0):
to(to),next(next),cost(cost) {}
}edge[N<<1];

void ins(int from,int to,int cost)
{
/*++sumedge;
edge[sumedge].to=to;
edge[sumedge].next=head[from];
edge[sumedge].cost=cost;*/
edge[++sumedge]=Edge(to,head[from],cost);
head[from]=sumedge;
}

int dis
,vis
,if_;

void SPFA(int now)
{
vis[now]=1;
for(int i=head[now];i;i=edge[i].next)
{
int go=edge[i].to;
if(dis[go]>dis[now]+edge[i].cost)
{
if(vis[go]||if_)
{
if_=1;
break;
}
dis[go]=dis[now]+edge[i].cost;
SPFA(go);
}
}
vis[now]=0;
}

void init()
{
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
if_=sumedge=0;
}

int main()
{
scanf("%d",&t);
for(;t;t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
ins(u,v,w);
if(w>=0) ins(v,u,w);
}
for(int i=1;i<=n;i++)
{
SPFA(i);
if(if_) break;
}
if(if_) printf("YE5\n");
else printf("N0\n");
}
return 0;
}

 

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