[2016-04-03][POJ][3259][Wormholes]
Posted 红洋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2016-04-03][POJ][3259][Wormholes]相关的知识,希望对你有一定的参考价值。
时间:2016-04-03 20:22:04 星期日
题目编号:[2016-04-03][POJ][3259][Wormholes]
题目大意:某农场有n个节点,m条边(双向)和w个虫洞(单向),(走虫洞可以回到过去的时间),问能否和过去的自己相遇
分析:
- 题目意思就是给定一个带负权的图,问是否存在负圈,
spfa_bfs
spfa_dfs
bellman_ford
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
//bfs_spfa
const int maxn = 500 + 10;
struct Edge{
int v,c;
Edge(int _v,int _c):v(_v),c(_c){}
};
vector<Edge> e[maxn];
void addedge(int u,int v,int c){
e[u].push_back(Edge(v,c));
}
bool vis[maxn];
int cnt[maxn],d[maxn];
bool spfa(int s,int n){
memset(vis,0,sizeof(vis));
memset(d,0x3f,sizeof(d));
memset(cnt,0,sizeof(cnt));
vis[s] = cnt[s] = 1;
d[s] = 0;
queue<int> q;
q.push(s);
while(!q.empty()){
int u = q.front();q.pop();
vis[u] = 0;
for(int i = 0 ;i < e[u].size();++i){
int v = e[u][i].v;
if(d[v] > d[u] + e[u][i].c){
d[v] = d[u] + e[u][i].c;
if(!vis[v]){
vis[v] = 1;
q.push(v);
if(++cnt[v] > n)
return false;
}
}
}
}
return true;
}
inline void ini(int n){//每组数据存图记得初始化
for(int i = 0; i <= n ; ++i){
e[i].clear();
}
}
int main(){
int f;
scanf("%d",&f);
while(f--){
int n,m,w;
scanf("%d%d%d",&n,&m,&w);
ini(n);
int s,e,t;
for(int i = 0;i < m ; ++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,t);
addedge(e,s,t);
}
for(int i = 0;i < w;++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,-t);
}
puts(spfa(1,n)?"NO":"YES");
}
return 0;
}
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
//dfs_spfa
const int maxn = 500 + 10;
struct Edge{
int v,c;
Edge(int _v,int _c):v(_v),c(_c){}
};
vector<Edge> e[maxn];
void addedge(int u,int v,int c){
e[u].push_back(Edge(v,c));
}
bool vis[maxn];
int d[maxn];
bool spfa(int u){
vis[u] = 1;
for(int i = 0 ;i < e[u].size();++i){
int v = e[u][i].v;
if(d[v] > d[u] + e[u][i].c){
d[v] = d[u] + e[u][i].c;
if(vis[v] || spfa(v)){
return 1;
}
}
}
vis[u] = 0;
return 0;
}
inline void ini(int n){
for(int i = 0; i <= n ; ++i){
e[i].clear();
}
memset(vis,0,sizeof(vis));
memset(d,0x3f,sizeof(d));
d[1] = 0;
}
int main(){
int f;
scanf("%d",&f);
while(f--){
int n,m,w;
scanf("%d%d%d",&n,&m,&w);
ini(n);
int s,e,t;
for(int i = 0;i < m ; ++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,t);
addedge(e,s,t);
}
for(int i = 0;i < w;++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,-t);
}
puts(spfa(1)?"YES":"NO");
}
return 0;
}
#include <vector>
#include <cstring>
#include <cstdio>
using namespace std;
//bellman_ford
const int maxn = 500 + 10;
struct Edge{
int u,v,c;
Edge(int _u,int _v,int _c):u(_u),v(_v),c(_c){}
};
vector<Edge> e;
void addedge(int u,int v,int c){
e.push_back(Edge(u,v,c));
}
int d[maxn];
bool bellman_ford(int s,int n){
memset(d,0x3f,sizeof(d));
d[s] = 0;
for(int i = 1;i < n ; ++i){
bool flg = 0;
for(int j = 0;j < e.size();++j){
int u = e[j].u,v = e[j].v,c = e[j].c;
if(d[v] > d[u] + c){
d[v] = d[u] + c;
flg = 1;
}
}
if(!flg) return 1;//没有负环
}
for(int j = 0;j < e.size();++j){
int u = e[j].u,v = e[j].v,c = e[j].c;
if(d[v] > d[u] + c) return 0;
}
return 1;
}
int main(){
int f;
scanf("%d",&f);
while(f--){
int n,m,w;
scanf("%d%d%d",&n,&m,&w);
e.clear();
int s,e,t;
for(int i = 0;i < m ; ++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,t);
addedge(e,s,t);
}
for(int i = 0;i < w;++i){
scanf("%d%d%d",&s,&e,&t);
addedge(s,e,-t);
}
puts(bellman_ford(1,n)?"NO":"YES");
}
return 0;
}
以上是关于[2016-04-03][POJ][3259][Wormholes]的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3259 Wormholes(bellman_ford判断负环)