poj 3259 Wormholes SPFA // Bellman-ford

2024-03-18 13:58

本文主要是介绍poj 3259 Wormholes SPFA // Bellman-ford,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

//最水的模版题,记下来以后忘了可以看看。

//SPFA

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=505;
int n, m, w, d[maxn], inqueue[maxn], cnt[maxn];
struct node{
    int e[maxn], v[maxn], sum;
}edge[maxn];

void add_edge(int s, int e, int v){
    edge[s].e[edge[s].sum]=e;
    edge[s].v[edge[s].sum]=v;
    edge[s].sum++;
}

void init(){
    int i, x, y, c;
    scanf("%d%d%d", &n, &m, &w);
    for(i=1; i<=n; i++){
        edge[i].sum=0;
        cnt[i]=0;
        inqueue[i]=0;
        d[i]=INF;
    }
    for(i=0; i<m; i++){
        scanf("%d%d%d", &x, &y, &c);
        add_edge(x, y, c);
        add_edge(y, x, c);
    }
    for(i=0; i<w; i++){
        scanf("%d%d%d", &x, &y, &c);
        add_edge(x, y, -c);
    }
}

bool spfa(int st){
    int i, head;
    queue<int > q;
    d[st]=0;
    inqueue[st]=1;
    q.push(st);
    cnt[st]=1;
    while(!q.empty()){
        head=q.front();
        q.pop();
        inqueue[head]=0;
        for(i=0; i<edge[head].sum; i++){
            if(d[edge[head].e[i]]>d[head]+edge[head].v[i]){
                d[edge[head].e[i]]=d[head]+edge[head].v[i];
                if(!inqueue[edge[head].e[i]]){
                    inqueue[edge[head].e[i]]=1;
                    cnt[edge[head].e[i]]++;
                    if(cnt[edge[head].e[i]]>=n)
                    return false;
                    q.push(edge[head].e[i]);
                }
            }
        }
    }
    return true;
}
int main(){
    //freopen("1.txt", "r", stdin);
    int T;
 scanf("%d", &T);
 while(T--){
  init();
  if(spfa(1))printf("NO\n");
  else printf("YES\n");
 }
    return 0;
}


//Bellman-ford
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int INF=0xfffffff;
int n, m, w, num, d[505];
struct node{
    int s, e, v;
}edge[5300];void Add_edge(int s, int e, int v){
    edge[num].s=s;
    edge[num].e=e;
    edge[num].v=v;
    num++;
}
void init(){
    int i, x, y, c;
    num=0;
    scanf("%d%d%d", &n, &m, &w);
    for(i=0; i<m; i++){
        scanf("%d%d%d", &x, &y, &c);
        Add_edge(x, y, c);
        Add_edge(y, x, c);
    }
    for(i=0; i<w; i++){
        scanf("%d%d%d", &x, &y, &c);
        Add_edge(x, y, -c);
    }
    for(i=1; i<=n; i++)
    d[i]=INF;
    d[1]=0;
}
bool bellman(){
    int i, j;
    for(i=1; i<n; i++){
        for(j=0; j<num; j++){
            if(d[edge[j].s]+edge[j].v<d[edge[j].e])
                d[edge[j].e]=d[edge[j].s]+edge[j].v;
        }
    }
    for(j=0; j<num; j++){
        if(d[edge[j].s]+edge[j].v<d[edge[j].e])
        return false;
    }
    return true;
}
int main(){
    //freopen("1.txt", "r", stdin);
 int i, T;
 scanf("%d", &T);
 while(T--){
  init();
  if(bellman())printf("NO\n");
  else printf("YES\n");
 }
 return 0;
}
 

 

这篇关于poj 3259 Wormholes SPFA // Bellman-ford的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822563

相关文章

poj 3882(Stammering Aliens) 后缀数组 或者 hash

后缀数组:  构建后缀数组,注意要在字符串莫末尾加上一个没出现过的字符。然后可以2分或者直接扫描,直接扫描需要用单调队列来维护 VIEW CODE #include<cstdio>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<string

poj 3294(Life Forms) 2分+ 后缀数组

我曾用字符串hash写,但是超时了。只能用后最数组了。大致思路:用不同的符号吧字符串连接起来,构建后缀数组,然后2分答案,依次扫描后缀数组,看是否瞒住条件。 VIEW CODE #include<cstdio>#include<vector>#include<cmath>#include<algorithm>#include<cstring>#include<cassert>#

poj 2391 Ombrophobic Bovines (网络流)

这是一道很经典的网络流的题目。首先我们考虑假如我们的时间为无穷大。我们吧每个点拆成2个点 i和i' .。虚拟源点s和汇点t。对于每个点建边(s,i, a[i])  (i‘,t,ib[i]) 。 其中a[i]为给点有多少牛,b[i]为容量。i和j连通 建边 (i,j',inf);如果最大流==所有牛的个数,就可能装下所有的牛。那么现在我们考虑时间。假设最大时间为T.那么如果i到j的的最短时间>T

poj 1330 LCA 最近公共祖先

水题目。直接上代码了。 VIEW CODE #include<cstdio>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<string>#include<cstring>#include<map>#include<vector>#

poj 3160 Father Christmas flymouse 强连通+dp

首先我们可以确定的是,对于val值小于0的节点都变成0.   假设一个集合内2个房间都能任意到达,那么我就可以吧集合内的所有点的价值都取到,并且可以达到任一点。实际上集合内的每个点是相同的,这样的集合就是一个强连通分量。 那么我们就可以用tarjin算法进行强连通缩点, 最后形成一个dag的图。在dag的图上面进行dp。可以先用拓扑排序后dp。或者建反响边记忆化搜索 。 VIEW

poj 1564 Sum It Up -- DFS 递归

题意:给一个数 t ,以及 n 个数,求 n 个数中的几个数加起来的和为 t 的情况有多少种。 注意:题目要求相同的组合方式不能出现2次,即 “3 4 1 1 1 1 ” 的结果为:“1+1+1”。 思路:一个  for  循环遍历一遍,每个 i 表示以当前数为起点开始一次DFS递归,当所遍历的和为 t 时,输出该组合方式,如果大于 t 则返回,小于则往下递归。以二维数组保存已经输出过的数据,

最短路算法总结(dijkstra,flyod,bellmanford,spfa)

总结 d i j k s t r a dijkstra dijkstra h e a p − d i j k s t r a heap-dijkstra heap−dijkstra b e l l m a n f o r d bellmanford bellmanford s p f a spfa spfa f l o y d floyd floyd最短路类型单源单源单源单源全源数据维护 e

道路 Road(百练,POJ)

题目链接: 1724 -- ROADS (poj.org) 题目描述: 思路: 这题目乍一看,是一个含有2个标尺的单源最短路问题,挺难处理的。 既然没法直接用最短路处理,那我们就“记录信息”,将花费的时间也记录进dp数组,然后跑“状态最短路”。 用f[i][j] 表示到达点i 且 总花费时间为j的最短距离,然后跑堆优化的dijkstra算法就好。由于不含有负边权,因此可以搞一个vis数

最大流的Ford-Fulkerson方法初步

网络或者网络流是一种基本的数据结构,而最大流则是网络流上的基本问题。网络本质上是一个符合一定条件的有向带权图。而最大流是最大可行流的简称,可行流是一个定义在网络流上的符合一定条件的函数。这些定义条件对于算法的正确性是不可缺少的,不过本文不描述可行流的数学条件,只介绍最大流最常用的Ford-Fulkerson方法的原理。     如上左的权图称作容量网络,边权值表示该边的容量。

最大流问题之Ford-Fulkerson

最大流问题的Ford-Fulkerson解法。可是说这是一种方法,而不是算法,因为它包含具有不同运行时间的几种实现。该方法依赖于三种重要思想:残留网络,增广路径和割。本文将会详细介绍这些内容,下一篇文章我们提供一种该方法的Java实现。 在介绍着三种概念之前,我们先简单介绍下Ford-Fulkerson方法的基本思想。首先需要了解的是Ford-Fulkerson是一种迭代的方法。