poj 3259 spfa/bellman判断负圈(虫洞)
来源:互联网 发布:人人商城小程序源码 编辑:程序博客网 时间:2024/06/09 19:26
题意:判断有向连通图(图中有重边)中是否存在负权环。给定N个点,M条双向正权边,W条单向负权边。
思路:用bellman或者spfa均可。在bellman算法中的表述为:在求出经过了n-1条边的最短路dist[k]之后,再对每条边<u,k>判断一下:加入这条边是否会使得顶点k的最短路径值再缩短,即判断:dist[u]+w(u,k)<dist[k] 是否成立,如果成立,则说明存在从源点可达的负权值回路。
在spfa中的表述为:若一个点最短路被改进的次数达 到n ,则有负权环。
bellman版本:
#include <stdio.h>#include <string.h>#define N 522int T,n,m,w,edgenum;struct edge{int x,y,w;}e[N*N/2];int dis[N];int bellman_ford(){int i,j;for(i = 0;i<n-1;i++){for(j = 0;j<edgenum;j++){if(dis[e[j].x]+e[j].w < dis[e[j].y]){dis[e[j].y] = dis[e[j].x]+e[j].w;}}}for(j = 0;j<edgenum;j++){if(dis[e[j].y] > dis[e[j].x]+e[j].w)return 1;}return 0;}int main(){//freopen("a.txt","r",stdin);scanf("%d",&T);while(T--){int i,x,y,len;edgenum = 0;memset(dis,0,sizeof(dis));scanf("%d %d %d",&n,&m,&w);for(i = 0;i<m;i++){scanf("%d %d %d",&x,&y,&len);e[edgenum].x = x;e[edgenum].y = y;e[edgenum++].w = len;e[edgenum].x = y;e[edgenum].y = x;e[edgenum++].w = len;}for(i = 0;i<w;i++){scanf("%d %d %d",&x,&y,&len);e[edgenum].x = x;e[edgenum].y = y;e[edgenum++].w = -len;}if(bellman_ford())printf("YES\n");elseprintf("NO\n");}return 0;}
spfa版本:
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <cstdlib>using namespace std;#define INF 0x3fffffff#define N 1005struct edge{ int y,next,w;}e[5205];int first[N],top,dis[N],num[N],used[N];int T,n,m,k;queue<int> q;void add(int x,int y,int w){ e[top].y = y; e[top].w = w; e[top].next = first[x]; first[x] = top++;}int relax(int x,int y,int w){ if(dis[y] > dis[x]+w){ dis[y] = dis[x]+w; return 1; } return 0;}int spfa(){ int i,now; q.push(1); for(i = 2;i<=n;i++) dis[i] = INF; dis[1] = 0; memset(num, 0, sizeof(num)); memset(used, 0, sizeof(used)); used[1] = 1; while(!q.empty()){ now = q.front(); q.pop(); used[now] = 0; for(i = first[now];i!=-1;i=e[i].next){ if(relax(now,e[i].y,e[i].w) && !used[e[i].y]){ used[e[i].y] = 1; q.push(e[i].y); num[e[i].y]++; if(num[e[i].y] == n) return 1; } } } return 0;}int main(){ scanf("%d",&T); while(T--){ int i,a,b,w; while(!q.empty()) q.pop(); memset(first, -1, sizeof(first)); top = 0; scanf("%d %d %d",&n,&m,&k); for(i = 1;i<=m;i++){ scanf("%d %d %d",&a,&b,&w); add(a,b,w); add(b,a,w); } for(i = 1;i<=k;i++){ scanf("%d %d %d",&a,&b,&w); add(a,b,-w); } if(spfa()) printf("YES\n"); else printf("NO\n"); } return 0;}
0 0
- poj 3259 spfa/bellman判断负圈(虫洞)
- POJ - 3259 Wormholes(判断负环, Bellman Ford,SPFA)
- POJ 3259 Wormholes(判断负权回路|SPFA||Bellman-Ford)
- POJ 3259 Wormholes(判断负环&(Bellman-Ford|SPFA))
- POJ 3259 Wormholes (判断负环,SPFA或Bellman-Ford都可)
- POJ 3259 判断负圈
- poj 3259 Wormholes (SPFA 判断有无负权回路)
- POJ 3259 Wormholes 判断负环(spfa)
- POJ 3259Wormholes(SPFA算法判断负权回路)
- poj 3259 Wormholes(spfa判断负环)
- (POJ 3259)Wormholes 判断负环 bellman_ford 或者 spfa
- POJ 3259 SPFA判断负权回路
- POJ:3259 Wormholes(SPFA判断负环)
- POJ 3259 Wormholes 【SPFA 判断负环】
- poj 3259 Wormholes 【SPFA&&判断负环】
- Poj 3259 Wormholes【spfa 负环判断】
- POJ 3259 Wormholes SPFA 判断负环
- 【POJ 3259】Wormholes (SPFA 判断负环)
- java基础之集合函数-Set
- hdu 5289 Assignment(数学)
- The C Programming Language 第三章控制流 读书笔记
- FirstChildElement() http://baike.baidu.com/link?url=VdlvQlGU-NGLshFepuft_u3MRdjZ9CAfGhOYuL915Oo-9pb
- 电影TS、TC、SCR、R5、BD、HD等版本是什么意思
- poj 3259 spfa/bellman判断负圈(虫洞)
- ios学习(block)
- 名企编程笔试题
- Leetcode 152 Maximum Product Subarray
- shell下的mysql
- 成员初始化列表顺序
- Java基础之集合函数-Map
- C++错误:不允许使用不完整的类型
- java网络编程一:Socket用法,简单模拟一对一聊天