POJ 1860 Currency Exchange + 2240 Arbitrage + 3259 Wormholes 解题报告

    三道题都是考察最短路算法的判环。其中1860和2240判断正环,3259判断负环。

    难度都不大,可以使用Bellman-ford算法,或者SPFA算法。也有用弗洛伊德算法的,笔者还不会SF-_-……

    直接贴代码。

    1860 Currency Exchange:

#include <cstdio>
#include <cstring>

int N,M,S;
double V;
const int maxn=101;
int first[maxn],vv[maxn*maxn],nxt[maxn*maxn];
double ww[maxn*maxn],cc[maxn*maxn];
double d[maxn];
int count[maxn];
int stack[maxn];
bool vis[maxn];

bool SPFA()
{
    for(int i=1;i<=N;i++)
        vis[i]=count[i]=d[i]=0;
    int top=0;
    stack[++top]=S;
    d[S]=V;
    vis[S]=true;
    count[S]++;

    while(top)
    {
        int a=stack[top--];
        vis[a]=false;

        for(int e=first[a];e;e=nxt[e])
        {
            if(d[vv[e]]<(d[a]-cc[e])*ww[e])
            {
                d[vv[e]]=(d[a]-cc[e])*ww[e];
                if(!vis[vv[e]])
                {
                    stack[++top]=vv[e];
                    count[vv[e]]++;
                    if(count[vv[e]]>=N)
                        return false;
                    vis[vv[e]]=true;
                }
            }
        }
    }
    return true;
}

int main()
{
//  freopen("in.txt","r",stdin);
    int e=2;
    scanf("%d%d%d%lf",&N,&M,&S,&V);
    for(int i=1;i<=M;i++)
    {
        int u,v;
        double w1,c1,w2,c2;
        scanf("%d%d%lf%lf%lf%lf",&u,&v,&w1,&c1,&w2,&c2);
        nxt[e]=first[u],vv[e]=v,ww[e]=w1,cc[e]=c1,first[u]=e++;
        nxt[e]=first[v],vv[e]=u,ww[e]=w2,cc[e]=c2,first[v]=e++;
    }
    printf(SPFA()?"NO\n":"YES\n");
}

    2240 Arbitrage:  起点不确定,需要枚举。map方便一点,hash……应该快一点

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#include <map>
#include <string>

const int maxn=31;
map<string,int> mp;
int first[maxn],vv[maxn*maxn],nxt[maxn*maxn];
double ww[maxn*maxn];
int stack[maxn];
double d[maxn];
int count[maxn];
bool vis[maxn];
int n;

int SPFA(int sta)
{
    int top=0;
    stack[++top]=sta;
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    memset(count,0,sizeof(count));
    count[sta]++;
    d[sta]=1;

    while(top)
    {
        int a=stack[top--];
        vis[a]=false;

        for(int e=first[a];e;e=nxt[e]) if(d[vv[e]]<d[a]*ww[e])
        {
            d[vv[e]]=d[a]*ww[e];
            if(!vis[vv[e]])
            {
                stack[++top]=vv[e];
                count[vv[e]]++;
                if(count[vv[e]]>=n)
                    return false;
                vis[vv[e]]=true;
            }
        }
    }
    return true;
}

int main()
{
//  freopen("in.txt","r",stdin);
    int cas=1;
    string str,str2;
    while(scanf("%d",&n) && n)
    {
        mp.clear();
        for(int i=1;i<=n;i++)
        {
            cin>>str;
            mp[str]=i;
        }

        memset(first,0,sizeof(first));

        int e=2;
        int m;
        scanf("%d",&m);
        while(m--)
        {
            cin>>str>>ww[e]>>str2;
            int u=mp[str];
            int v=mp[str2];
            nxt[e]=first[u],vv[e]=v,first[u]=e++;
        }

        bool flag=false;
        for(int i=1;i<=n;i++) if(!SPFA(i))
            flag=true;
        printf("Case %d: ",cas++);
        printf(flag?"Yes\n":"No\n");
    }
}

     3259 Wormholes:

#include <cstdio>
#include <cstring>

int first[501],vv[6000],ww[6000],nxt[6000];
int d[501];

bool relax(int u,int v,int w)
{
    if(d[v]<=d[u]+w) return false;
    d[v]=d[u]+w;
    return true;
}

bool bellman_ford(int n)
{
    memset(d,0,sizeof(d));

    bool flag;
    for(int i=1;i<=n;i++)
    {
        flag=true;
        for(int u=1;u<=n;u++)
            for(int e=first[u];e;e=nxt[e])
                if(relax(u,vv[e],ww[e]))
                    flag=false;
        if(flag)
            return true;
        else if(i==n)
            return false;
    }
    return true;
}

int main()
{
//  freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);

    while(T--)
    {
        int N,M,W;
        scanf("%d%d%d",&N,&M,&W);
        int e=2;
        int u,v,w;

        memset(first,0,sizeof(first));
        for(int i=0;i<M;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            nxt[e]=first[u],vv[e]=v,ww[e]=w,first[u]=e++;
            nxt[e]=first[v],vv[e]=u,ww[e]=w,first[v]=e++;
        }
        for(int i=0;i<W;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            nxt[e]=first[u],vv[e]=v,ww[e]=-w,first[u]=e++;
        }

        if(bellman_ford(N))
            printf("NO\n");
        else
            printf("YES\n");
    }
}

 

posted @ 2013-07-27 15:22  SF-_-  阅读(322)  评论(0编辑  收藏  举报