首页 > 代码库 > POJ 3767 I Wanna Go Home

POJ 3767 I Wanna Go Home

这题是很明显的最短路,我用的是SPFA算法。题目中有一个要求就是只能走一次从1到2,所以我用了一个belong数组来记录,在求最短路的时候,先判断是从1到2,还是从2到1,如果是后者,那么就忽略。最后判断是否存在,只要看dist[2]是否有值就可以了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int N=605;
const int M=10005;
const int inf=100000000;
int dist[N],head[N],belong[N];
bool visited[N];
int top,n,m;
struct Road
{
    int v,w;
    int next;
}road[2*M];
void add_edge(int u,int v,int w)
{
    road[top].v=v,road[top].w=w;
    road[top].next=head[u];
    head[u]=top++;
}
void spfa()
{
    memset(visited,false,sizeof(visited));
    fill(dist,dist+N,inf);
    queue<int> q;
    q.push(1);
    dist[1]=0;
    visited[1]=true;
    int cur,_next;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        visited[cur]=false;
        for(int i=head[cur];i!=-1;i=road[i].next)
        {
            _next=road[i].v;
            if(belong[cur]==2&&belong[_next]==1)
                continue;
            int t=dist[cur]+road[i].w;
            if(dist[_next]>t)
            {
                dist[_next]=t;
                if(visited[_next]==false)
                {
                    visited[_next]=true;
                    q.push(_next);
                }
            }
        }
    }
}
int main()
{
    int a,b,t;
    while(scanf("%d",&n))
    {
        if(n==0)
            break;
        scanf("%d",&m);
        memset(head,-1,sizeof(head));
        top=1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&t);
            add_edge(a,b,t);
            add_edge(b,a,t);
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&belong[i]);
        spfa();
        if(dist[2]>=inf)
            printf("-1\n");
        else
            printf("%d\n",dist[2]);
    }
    return 0;
}


POJ 3767 I Wanna Go Home