poj2263 zoj1952 Heavy Cargo(floyd||spfa)

这道题数据范围小,方法比较多。我用floyd和spfa分别写了一下,spfa明显有时间优势。

一个小技巧在于:把城市名称对应到数字序号,处理是用数字。

方法一:spfa

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const int eps=1e-8;
const int INF=1000000000;
const int maxn=200+10;
int n,r,cas=0,ton,num,used[maxn],d[maxn],m[maxn][maxn];
char city[maxn][33];
char s[33],e[33];
vector<int>v[maxn];
int index(char *ss)
{
    int i;
    for(i=0;i<num;i++)
    {
        if(strcmp(ss,city[i])==0)
        {
            return i;
        }
    }
    strcpy(city[num++],ss);
    return i;
}
void ini()
{
    num=0;
    for(int i=0;i<n;i++)
    {
        strcpy(city[i],"");
        v[i].clear();
        used[i]=0;
        d[i]=INF;
    }
}
int spfa(int s,int e)
{
    queue<int>q;
    q.push(s);
    used[s]=1;
    while(!q.empty())
    {
        int t=q.front();
        used[t]=0;
        q.pop();
        int siz=v[t].size();
        for(int i=0;i<siz;i++)
        {
            int k=v[t][i];
            /*if(used[k]==0) {q.push(k);used[k]=1;}
            if(d[k]<INF) d[k]=max(d[k],min(d[t],m[t][k]));
            else d[k]=min(d[t],m[t][k]);*/
            /*上面注释掉的这种写法不对,一旦有环就会陷入死循环(即使这题不会有
            负边)。还是对spfa理解的不够。需要更新的点才要考虑入队的问题,不需要
            更新的点肯定不入队,最后所有点都不用再更新了队列为空退出循环。而不是
            遇到一个点就入队。*/
            if(d[k]==INF)
            {
                d[k]=min(d[t],m[t][k]);
                q.push(k);used[k]=1;
            }
            else if(min(d[t],m[t][k])>d[k])
            {
                d[k]=min(d[t],m[t][k]);
                if(used[k]==0) {q.push(k);used[k]=1;}
            }
        }
    }
    return d[e];
}
int main()
{
    //freopen("in8.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d%d",&n,&r)==2)
    {
        if(n==0&&r==0) break;
        printf("Scenario #%d
",++cas);
        ini();
        for(int i=0;i<r;i++)
        {
            scanf("%s%s%d",s,e,&ton);
            int t1=index(s);
            int t2=index(e);
            v[t1].push_back(t2);
            v[t2].push_back(t1);
            m[t1][t2]=m[t2][t1]=ton;
        }
        scanf("%s%s",s,e);
        int t1=index(s);
        int t2=index(e);
        printf("%d tons
",spfa(t1,t2));
        printf("
");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
spfa

方法二:floyd

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const int eps=1e-8;
const int INF=1000000000;
const int maxn=200+10;
int n,r,m[maxn][maxn],cas=0,ton,num;
char city[maxn][33];
char s[33],e[33];
int index(char *ss)
{
    int i;
    for(i=0;i<num;i++)
    {
        if(strcmp(ss,city[i])==0)
        {
            return i;
        }
    }
    strcpy(city[num++],ss);
    return i;
}
void floyd()
{
    for(int k=0;k<n;k++)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                m[i][j]=max(m[i][j],min(m[i][k],m[k][j]));
            }
        }
    }
}
void ini()
{
    num=0;
    for(int i=0;i<n;i++)
    {
        strcpy(city[i],"");
        for(int j=0;j<n;j++)
        {
            if(i==j) m[i][j]=INF;
            else m[i][j]=0;
        }
    }
}
int main()
{
    //freopen("in8.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d%d",&n,&r)==2)
    {
        if(n==0&&r==0) break;
        printf("Scenario #%d
",++cas);
        ini();
        for(int i=0;i<r;i++)
        {
            scanf("%s%s%d",s,e,&ton);
            int t1=index(s);
            int t2=index(e);
            m[t1][t2]=m[t2][t1]=ton;
        }
        floyd();
        scanf("%s%s",s,e);
        int t1=index(s);
        int t2=index(e);
        printf("%d tons
",m[t1][t2]);
        printf("
");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
floyd
原文地址:https://www.cnblogs.com/zywscq/p/4102787.html