ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1038 虫洞 Wormholes 判断负环+各种细节

2022-08-24 02:03:34  阅读:169  来源: 互联网

标签:le ver int 负环 vis 1038 Wormholes dist John


 链接:https://ac.nowcoder.com/acm/contest/26077/1038
来源:牛客网

题目描述

John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N(从1到N标号)块地,并有W个虫洞。
现在John想借助这些虫洞来回到过去(在出发时刻之前回到出发点),请你告诉他能办到吗。John将向你提供F个农场的地图。没有小路会耗费你超过10410^4104秒的时间,当然也没有虫洞回帮你回到超过10410^4104秒以前。

输入描述:

第一行一个整数F,表示农场个数;
对于每个农场:
第一行,三个整数N,M,W;
接下来M行,每行三个数S,E,T,表示在标号为S的地与标号为E的地中间有一条用时T秒的小路;
接下来W行,每行三个数S,E,T,表示在标号为S的地与标号为E的地中间有一条可以使John到达T秒前的虫洞。

输出描述:

输出共F行,如果John能在第i个农场实现他的目标,就在第i行输出YES,否则输出NO。
示例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

输出

复制
NO
YES

备注:

对于全部数据,1≤F≤5,1≤N≤500,1≤M≤2500,1≤W≤200,1≤S,E≤N,∣T∣≤1041 \le F \le 5,1 \le N \le 500,1 \le M \le 2500,1 \le W \le 200,1 \le S,E \le N,|T| \le10^41≤F≤5,1≤N≤500,1≤M≤2500,1≤W≤200,1≤S,E≤N,∣T∣≤104。

分析

1.如果存在负环,则这条负环至少经过n 个点。这样是o(n)

2.如果记录每个点入队次数就要o(n^2)

3.由于可能负环不在根节点位置,所以要预先把所有点放进队列里。

ps:不要忘记初始化

//-------------------------代码----------------------------

//#define int ll
const int N = 1e6+10;
int n,m,w;
V<pii> e[N];
int dist[N];
bool vis[N];
int cnt[N];

bool spfa(int st) {
    ms(dist,0x3f);ms(vis,0);
    queue<int> q;
    fo(i,1,n) {
        dist[i] = 0;
        vis[i] = 1;
        q.push(i);
        cnt[i] = 0;
    }
    while(q.size()) {
        auto t = q.front();q.pop();
        vis[t] = 0;
        for(auto it:e[t]) {
            int ver = it.first,W = it.second;
            if(dist[ver] > dist[t] + W) {
                dist[ver] = dist[t] + W;
                cnt[ver] = cnt[t] + 1;
                if(cnt[ver] >= n) return 1;
                if(!vis[ver])q.push(ver),vis[ver] = 1;
            }
        }
    }
    return 0;
}

void solve()
{
    cin>>n>>m>>w;
    fo(i,1,n) e[i].clear();
    fo(i,1,m) {
        int a,b,c;cin>>a>>b>>c;
        e[a].pb({b,c}),e[b].pb({a,c});
    }
    fo(i,1,w) {
        int a,b,c;cin>>a>>b>>c;
        e[a].pb({b,-c});
    }
    if(spfa(1)) {
        YES;
    } else {
        NO;
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

标签:le,ver,int,负环,vis,1038,Wormholes,dist,John
来源: https://www.cnblogs.com/er007/p/16618399.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有