POJ2240 spfa判增大环 poj3259 spfa判负环

poj2240

题目:
想利用美元套利,就是100美元->50英镑->500发廊->105美元
问有没有这种路径能利用美元套利
思路:
①map处理
②spfa判正环,咦?spfa不是判负环吗,怎么判正环啊,也是个思维哦!
③一些写法,也可以用链式前向星,我用的vector邻接表,因为这个题最大N为30,只要写对,不用关心算复杂度了

#include <iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
int n,m;
queue<int> cun;
typedef pair<int,double> pid;
map<string,int> si;
vector<pid> tu[50];
vector<pid>::iterator it;

double dis[50];
int vis[50];
int spfa()
{
    while(!cun.empty())
        cun.pop();
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));       //zhege????
    dis[1]=1.0;
    cun.push(1);
    vis[1]=1;
    while(!cun.empty())
    {
        int t=cun.front();
        cun.pop();
        vis[t]=0;
        for(it=tu[t].begin(); it!=tu[t].end(); it++)
        {
            int v=it->first;
            double w=it->second;
            if(dis[v]<dis[t]*w)
            {
                dis[v]=dis[t]*w;
                if(!vis[v])
                {
                    cun.push(v);
                    vis[v]=1;
                }
            }

        }
        if(dis[1]>1)
        {
            return 1;
        }
    }
    if(dis[1]>1)
    {
        return 1;
    }
    return 0;


}

int main()
{
    int ttt=1;
    string a,b;
    int u,v;
    while(scanf("%d",&n)!=EOF&&n)
    {

        string str;
        si.clear();
        for(int i=1; i<=n; i++)
        {
            cin>>str;
            tu[i].clear();
            si[str]=i;
        }

        cin>>m;
        double zhi;
        for(int j=0; j<m; j++)
        {
            cin>>a>>zhi>>b;

            u=si[a];
            v=si[b];
            tu[u].push_back({v,zhi});
        }
        cout<<"Case "<<ttt++<<": ";
        if(spfa()==1)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;

    }
    return 0;

}


poj3259

题意:一个农场有m条无向边,每边花费时间C x条单向虫洞,每次进入虫洞,返回时间C然后到另一结点
问能不能见到过去的自己;
思路:判负环问题,如果一个点能优化n次以上,就说明有负环。

#include <iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
int x,y;
int n,m;
queue<int> cun;
typedef pair<int,int> pii;
vector<pii> tu[505];
vector<pii>::iterator it;
int dis[505],vis[505];
int cnt[505];
int spfa(){
    while(!cun.empty())cun.pop();
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    memset(dis,0x3f,sizeof(dis));
    cun.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!cun.empty()){
        int tmp=cun.front();
        cun.pop();
        cnt[tmp]++;
                if(cnt[tmp]>n){
                                        return -1;
                                    }
        vis[tmp]=0;

        for(it=tu[tmp].begin();it!=tu[tmp].end();it++){
            int w=it->second;
            int v=it->first;
            if(dis[v]>dis[tmp]+w){
                dis[v]=dis[tmp]+w;
                        if(!vis[v]){

                                            cun.push(v);
                                            vis[v]=1;

                                    }
            }
        }

    }



    return 0;
}
int main()
{
    int t;
    int a,b,c;
    scanf("%d",&t);
    while(t--){
            memset(cnt,0,sizeof(cnt));
        scanf("%d %d %d",&n,&m,&x);
        for(int i=1;i<=n;i++)tu[i].clear();
        while(m--){
            scanf("%d %d %d",&a,&b,&c);
            tu[a].push_back({b,c});
            tu[b].push_back({a,c});
        }
        while(x--){
            scanf("%d %d %d",&a,&b,&c);
            tu[a].push_back({b,-c});
        }
        if(spfa()==-1){
        printf("YES\n");
    }
    else
                printf("NO\n");


    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值