poj3259
Posted KasenBob
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3259相关的知识,希望对你有一定的参考价值。
1.链接地址
https://vjudge.net/problem/POJ-3259#author=chen_zhe_
2.问题描述
教学楼里有很多教室,这些教室由双向走廊连接。另外,还存在一些单向的秘密通道,通过它们可以回到过去。现在有 N (1 ≤ N ≤ 500) 个教室,编号 1..N, M (1 ≤ M ≤ 2500) 条走廊,和 W (1 ≤ W ≤ 200) 条秘密通道。
DY在养猫之余,还是一个时间旅行爱好者。她希望从一间教室出发,经过一些走廊和秘密通道,回到她出发之前的某个时间。
共有F (1 ≤ F ≤ 5) 组数据。对每组数据,判断DY是否有回到过去的可能性。不存在耗时超过10,000秒的走廊,且不存在能带DY回到10,000秒之前的秘密通道。
输入样例
2 3 3 1 1 2 2 1 3 4 2 3 1 3 1 3 3 2 1 1 2 3 2 3 4 3 1 8
输出样例
NO YES
3.解题思路
本题适合使用Bellman-ford算法判断是否有负权边
注意走廊是双向的,需要双向计算,但是秘密通道是单向的,只需要计算一次
4.算法实现源代码
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int maxn = 510; const int maxw = 2500*2+200+10; const int INF = 10000; int d[maxn]; int n,m; struct Edge{ int u,v; int t; }edge[maxw]; bool bellman_ford() { for(int i = 1; i <= n; i++) d[i] = INF; d[1] = 0; for(int i = 1; i < n; i++) { bool flag = true; for(int j = 0; j < m; j++) { int u = edge[j].u; int v = edge[j].v; int t = edge[j].t; if(d[v] > d[u]+t) { d[v] = d[u]+t; flag = false; } } if(flag) return false; } for(int i = 0; i < m; i++) { if(d[edge[i].v] > d[edge[i].u]+edge[i].t) return true; } return false; } int main() { int T; int M,W; scanf("%d", &T); while(T--) { scanf("%d%d%d", &n,&M,&W); m = 0; int u,v,t; for(int i = 1; i <= M; i++) { scanf("%d%d%d", &u,&v,&t); edge[m].u = u; edge[m].v = v; edge[m++].t = t; edge[m].u = v; edge[m].v = u; edge[m++].t = t; } for(int i = 1; i <= W; i++) { scanf("%d%d%d", &u,&v,&t); edge[m].u = u; edge[m].v = v; edge[m++].t = -t; } if(bellman_ford()) printf("YES\n"); else printf("NO\n"); } }
以上是关于poj3259的主要内容,如果未能解决你的问题,请参考以下文章