poj 3259 worm-holes spfa判断负权回路
2017-03-23 17:07
435 查看
B - Wormholes
POJ - 3259 如果没有负权回路,则一个点的被松弛的次数一定小于等于n-1。
所以如果某个点进出超过这个次数,则说明存在负权边,即可以沿负边一直走,
陷入死循环。。。
spfa模板+前向星。
#include<cstdio>
#include<cstring>
#include<iostream>
#include <cmath>
#include <queue>
using namespace std ;
const int inf = 0x3f3f3f3f;
const int MAXN = 10005;
bool vis[MAXN];
int Count[MAXN];
int head[MAXN];
struct node
{
int to, next;
int c;
} G[MAXN];
int cnt;
int dist[MAXN];
int n;
void add(int u, int v, int c)
{
G[cnt].to=v;
G[cnt].c=c;
G[cnt].next=head[u];
head[u]=cnt++;
}
bool spfa(int s)
{
int u, v;
queue <int> q;
memset(vis, false, sizeof(vis));
memset(Count, 0, sizeof(Count));
for(int i=1; i<=n; ++i)
dist[i]=inf;
q.push(s),Count[s]++,vis[s]=true, dist[s]=0;
while(!q.empty())
{
u = q.front();
q.pop();
vis[u]=0;
for(int i=head[u]; ~i; i=G[i].next)
{
v=G[i].to;
if(dist[v]>dist[u]+G[i].c)
{
dist[v]=dist[u]+G[i].c;
if(!vis[v])
{
vis[v]=1;
q.push(v);
Count[v]++;
if(Count[v]>n-1)
return true;
}
}
}
}
return false;
}
int main()
{
int t, u, v, m, c, w;
scanf("%d", &t);
while(t--)
{
scanf("%d %d %d", &n, &m, &w);
cnt=0;
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d %d %d", &u, &v, &c);
add(u, v, c);
add(v, u, c);
}
while(w--)
{
scanf("%d %d %d", &u, &v, &c);
add(u, v, -c);
}
if(spfa(1))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
还有一种就是bellman-ford
#include <stdio.h>
#define maxN 502
#define maxM 2702
#define inf 1000000000
struct EDGE
{
int u,v,w;
}edge[2 * maxM];
int dis[maxN];
int N, M, W;
int edgeNum;
void Init()
{
for (int i = 0; i <= N; ++ i)
{
dis[i] = inf;
}
}
bool bellMan(void)
{
bool flag;
for (int i = 0; i < N - 1; ++ i)
{
flag = false;
for (int j = 0; j < edgeNum; ++ j)
{
if (dis[edge[j].v] > dis[edge[j].u] + edge[j].w)//松弛
{
dis[edge[j].v] = dis[edge[j].u] + edge[j].w;
flag = true;
}
}
if (!flag)//存在负权回路
{
break;
}
}
for (int i = 0; i < edgeNum; ++ i)
{
if(dis[edge[i].v] > dis[edge[i].u] + edge[i].w)
return true;
}
return false;
}
int main()
{
int F;
scanf("%d", &F);
while (F --)
{
scanf("%d%d%d", &N, &M, &W);
edgeNum = 0;
Init();
int u,v,w;
for (int i = 1; i <= M; ++ i)
{
scanf("%d%d%d", &u, &v, &w);//正权双向
edge[edgeNum].u = u;
edge[edgeNum].v = v;
edge[edgeNum].w = w;
edgeNum ++;
edge[edgeNum].u = v;
edge[edgeNum].v = u;
edge[edgeNum].w = w;
edgeNum ++;
}
for (int i = 1; i <= W; ++ i)
{
scanf("%d%d%d", &u, &v, &w);
edge[edgeNum].u = u;
edge[edgeNum].v = v;
edge[edgeNum].w = -w;//负权
edgeNum ++;
}
if(bellMan())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
相关文章推荐
- POJ 3259 Wormholes(判断负权回路|SPFA||Bellman-Ford)
- Wormholes POJ 3259 SPFA 判断是否出现了负权值回路
- POJ_3259(Wormholes)(SPFA判断负权回路)
- poj 3259 wormholes AC代码(负权环判断, Bellmanford)
- Poj 3259 Wormholes【SPFA判断负权回路】
- F - Wormholes POJ - 3259--SPFA 算法判断负环是否存在
- POJ 3259 Wormholes Bellman判断负权环 .
- poj 3259 Wormholes spfa判断负环 解题报告
- poj 3259 Wormholes SPFA判断 负权值环
- POJ 3259 Wormholes SPFA 判断负环
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- poj 3259 spfa判断回路。
- POJ 3259 Wormholes(SPFA or BELL_MAN)
- POJ - 3259 Wormholes解题报告(SPFA判断负权环)
- poj 3259 (SPFA,求是否有负权回路)
- Wormholes POJ 3259【SPFA】
- POJ 3295 spfa判断是否存在负权回路
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- POJ No 3259 Wormholes Bellman-Ford 判断是否存在负图
- Wormholes poj 3259 (bellman-floyd+spfa)