首页 > 其他分享 >[USACO06DEC] Wormholes G(spfa判断环)

[USACO06DEC] Wormholes G(spfa判断环)

时间:2024-05-23 22:59:02浏览次数:28  
标签:cnt le dist USACO06DEC idx int d% spfa Wormholes

[USACO06DEC] Wormholes G

题目背景

英文题面见此链接

题目描述

John 在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。

John 的每个农场有 m m m 条小路(无向边)连接着 n n n 块地(从 1 ∼ n 1 \sim n 1∼n 标号),并有 w w w 个虫洞。

现在 John 希望能够从某块地出发,走过一条路径回到出发点,且同时也回到了出发时刻以前的某一时刻。请你告诉他能否做到。

输入格式

输入的第一行是一个整数 T T T,代表测试数据的组数。

每组测试数据的格式如下:

每组数据的第一行是三个用空格隔开的整数,分别代表农田的个数 n n n,小路的条数 m m m,以及虫洞的个数 w w w。

每组数据的第 2 2 2 到第 ( m + 1 ) (m + 1) (m+1) 行,每行有三个用空格隔开的整数 u , v , p u, v, p u,v,p,代表有一条连接 u u u 与 v v v 的小路,经过这条路需要花费 p p p 的时间。

每组数据的第 ( m + 2 ) (m + 2) (m+2) 到第 ( m + w + 1 ) (m + w + 1) (m+w+1) 行,每行三个用空格隔开的整数 u , v , p u, v, p u,v,p,代表点 u u u 存在一个虫洞,经过这个虫洞会到达点 v v v,并回到 p p p 秒之前。

输出格式

对于每组测试数据,输出一行一个字符串,如果能回到出发时刻之前,则输出 YES,否则输出 NO

样例 #1

样例输入 #1

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

样例输出 #1

NO
YES

提示

样例 2 解释

John 只需要沿着 1 → 2 → 3 → 1 1 \rightarrow 2 \rightarrow 3 \rightarrow 1 1→2→3→1 的路径一直转圈即可,每转完一圈,时间就会减少一秒。

数据范围与约定

对于 100 % 100\% 100% 的数据, 1 ≤ T ≤ 5 1 \le T \le 5 1≤T≤5, 1 ≤ n ≤ 500 1 \le n \le 500 1≤n≤500, 1 ≤ m ≤ 2500 1 \le m \le 2500 1≤m≤2500, 1 ≤ w ≤ 200 1 \le w \le 200 1≤w≤200, 1 ≤ p ≤ 1 0 4 1 \le p \le 10^4 1≤p≤104。

思路

这就是很典型的判断是否有环的题目。

代码

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>

using namespace std;

const int N = 2e4+10;

int e[N],ne[N],w[N],h[N],idx;
bool st[N];
int dist[N];
int cnt[N];
int n,m,k;
int T;

void add(int a,int b,int c){
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

bool spfa(){
    queue<int>q;
    memset(dist,0,sizeof dist);
    memset(cnt,0,sizeof cnt);
    memset(st,0,sizeof st);
    
    for(int i=1;i<=n;i++){
        q.push(i);
        st[i]=true;
    }
    
    while(q.size()){
        int t=q.front();
        q.pop();
        st[t]=false;
        
        for(int i=h[t];~i;i=ne[i]){
            int j=e[i];
            
            if(dist[j]>dist[t]+w[i]){
                dist[j]=dist[t]+w[i];
                cnt[j]=cnt[t]+1;
                if(cnt[j]>=n)return false;
                if(!st[j]){
                    st[j]=true;
                    q.push(j);
                }
            }
        }
    }
    
    return true;
}

int main(){
    // ios::sync_with_stdio(false);
    scanf("%d",&T);
    
    while(T--){
        memset(h,-1,sizeof h);
        idx=0;
        // memset(dist,0x3f,sizeof dist);
        
        // cin>>n>>m>>k;
        scanf("%d%d%d",&n,&m,&k);
        
        for(int i=1;i<=m;i++){
            int a,b,c;
            // cin>>a>>b>>c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        
        for(int i=1;i<=k;i++){
            int u,v,p;
            // cin>>u>>v>>p;
            scanf("%d%d%d",&u,&v,&p);
            add(u,v,-p);
        }
        
        if(!spfa()){
            puts("YES");
        }else{
            puts("NO");
        }
    }
    
    return 0;
}

标签:cnt,le,dist,USACO06DEC,idx,int,d%,spfa,Wormholes
From: https://blog.csdn.net/m0_60738889/article/details/139131585

相关文章

  • SPFA
    这算是我的第一篇使用LaTeX的文章易写,支持负权,可判负环,可以求最短路,也可以最长路,什么都行。就是容易被卡qwq所以SPFA他死了。是Bellman_Ford算法的队列优化版。使用范围支持负权,可以处理负环,可判负环,可以求最短路,也可以求最长路。平均时间复杂度\(O(m)\),极限时间复杂度为\(......
  • P2853 [USACO06DEC] Cow Picnic S
    简单的一道深搜:思路:让每个有奶牛的农场沿着道路跑下去,跑到的农场加上root地方的奶牛数量,最后统计能有k头奶牛的农场数量就是答案代码:#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#inclu......
  • SPFA算法
    单源最短路算法,可以处理负边权,平均时间复杂度\(O(kn)\),最坏时间复杂度\(O(mn)\)问题描述:有一个连通图\(G=(V,E)\),连接节点\(i\)和节点\(j\)的边权写作\(e^i_j\)(\(e^i_j\geq0\)),求从起点(\(s,s\inV\))开始,到其它各个节点(\(d,d\inV-s\))的最短路长度。思路详解:设从起点s到节点d......
  • 最短路算法(Dijkstra + SPFA + Floyd)
    最短路算法(Dijkstra+SPFA+Floyd)Dijkstra算法1.算法基本介绍Dijkstra算法通常是求解单源最短路中最快的算法,但它无法处理存在负权边的情况(原因在正确性证明中)。Dijkstra本质上是一种贪心算法,通过不断调整每个点的“当前距离”最终得到最优结果,其实后面要讲到的几种算法也大......
  • 【学习笔记】spfa
    一、spfa模板:voidspfa(intx){ for(inti=1;i<=n;i++) vis[i]=0,dis[i]=inf; dis[1]=0,f[1]=1; q.push(1); while(!q.empty()) { intt=q.front(); q.pop(); vis[t]=0; for(inti=first[t];i;i=e[i].next) { intto=e[i].to; if(dis[t]+e[i].v<......
  • 洛谷题单指南-图的基本应用-P2853 [USACO06DEC] Cow Picnic S
    原题链接:https://www.luogu.com.cn/problem/P2853题意解读:找到所有奶牛都可以到达的牧场,就是要从奶牛所在位置开始遍历,求所有奶牛能重合的点的个数。解题思路:直接从从牛奶所在位置进行DFS,记录每个位置有奶牛能到的个数,个数等于奶牛总数的即合适的牧场。100分代码:#include<bi......
  • P2854 [USACO06DEC] Cow Roller Coaster S
    原题链接题解1.当没有花费限制的时候,我们可以将其抽象为简单的背包问题2.如果有了花费限制,那么我们就再加一维条件3.如果一个线段能用,那么它前面一定是铺满的,那我们令线段按起点排序,通过某种运算,保证放这个线段时,前面的线段组成是最优的比如在\(i\)点结尾位置花费\(j\)所......
  • P2850 [USACO06DEC] Wormholes G
    原题链接题解1.虫洞等价于建立负权边2.回到过去等价于存在负权环这里就相当于检测是否存在负权环,怎么判定呢?广搜,对于任意不含有负权环的,任意两点间的点数一定小于n如果存在负权环,那么搜索会一直沿着这个环进行下去,其路径的点数会大于ncode#include<bits/stdc++.h>usingna......
  • spfa优化
    \(spfa\)的优化都是基于\(deque\)的,我们通常使用\(LLL\)优化,代码简单,优化效果最好,详情可见参考这里,例题可以参考这里1.\(LLL\)优化(入队优化)LargeLabelLast优化:思路就是将\(dist\)更大的点放入队尾,将\(dist\)更小的点放入队头,优先使用\(dist\)更小的点进行松弛操......
  • 关于spfa
    “正常”求最短路BFS版本voidspfa(){queue<int>q;q.push(0);fl[0]=1;while(q.size()){intx=q.front(); q.pop(); fl[x]=0; for(inti=h[x];i;i=s[i].next){ inty=s[i].to; if(dis[y]<dis[x]+s[i].w){ ......