DUT 胡老师的跨国逃亡

Description

A国与B国又爆发了战争,这让正在A国工作的B国人胡老师非常危险。大陆上只有这两个国家的存在,这让胡老师无处避难,思乡心切的胡老师希望在战争期间尽快回到家乡。
大陆上有N (2<=N<=3000)座城市,标号1...N,由M (0<=M<=500000)条道路连接,每条道路都是双向连接的,并且长度为W(0<=W<=500),我们把连接不同国家的城市的道路叫做边境道路。我们假定胡老师在1号城市工作,家乡在2号城市,并且假定1号城市一直属于A国,2号城市一直属于B国。
“两国交战,屯兵边境,过边境实在是太危险了。”一个美眉这样告诉她敬爱的胡老师,是啊,在这样敏感的时候离开A国,可能会被当间谍处理的。为了安全着想,又为了尽快回到家乡城市,胡老师决定选择一条最短路线,并且这个路线至多只包含一条边境道路。
所谓关心则乱,现在的胡老师已经失去思考能力了,你能帮助胡老师选择这样一条道路吗?

Input

第1行输入一个整数N。
第2行输入一个整数M。
接下来的M行,每行输入三个整数A、B、W,代表A、B之间有道路,长度为W。
最后一行输入N个整数,每个整数为1或2,分别代表i号城市属于哪个国家,1代表A国,
2代表B国。

Output

每个输入对应一行输出,输出一个整数代表满足条件的路径的长度,如果不存在这样的路径,请输出-1。

Sample Input

2
1
1 2 100
1 2

3
3
1 2 100
1 3 40
2 3 50
1 2 1

5
5
3 1 200
5 3 150
2 5 160
4 3 170
4 2 170
1 2 2 2 1

Sample Output

100
90
540

#include<iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int MAXE = 500000;
const int MAXN = 4000;
const int inf=0x7fffffff;

int N,M;
queue <int> que;
int mark[MAXN+10];
int box[MAXN+10],dis[MAXN+10],ecnt;

struct node
{
    int to,next,val;
}edge[MAXE*3];

struct tv
{
    int from,to,val;
}mypoint[MAXE*3];

void _make_map(int from,int to,int val)
{
	edge[ecnt].to=to;
	edge[ecnt].val=val;
	edge[ecnt].next=box[from];
	box[from]=ecnt++;
}

void make_map(int from,int to,int val)
{
	_make_map(from,to,val);
	_make_map(to,from,val);
}

void SPFA(int start,int f)
{
    while(!que.empty()) {que.pop();}
    bool flag[MAXN];
    memset(flag,false,sizeof(flag));
    dis[start]=0,que.push(start);
    while(!que.empty())
    {
        int x=que.front();que.pop(),flag[x]=false;
        for(int i=box[x];~i;i=edge[i].next)
        if((mark[edge[i].to]==f)&&(dis[edge[i].to]-dis[x]>edge[i].val))
        {
            dis[edge[i].to]=dis[x]+edge[i].val;
            if(!flag[edge[i].to])flag[edge[i].to]=true,que.push(edge[i].to);
        }
    }
}

int main()
{
    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        ecnt=0;
        memset(mark,0,sizeof(mark));
        memset(box,-1,sizeof(box));
        int x,y,val;

        for(int i=0;i<M;i++)
        {
            scanf("%d%d%d",&x,&y,&val);
            make_map(x,y,val);
            tv t;
            t.from=x;
            t.to=y;
            t.val=val;
            mypoint[i]=t;
        }
        int f;
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&f);
            mark[i]=f;
        }
        memset(dis,127,sizeof(dis));

        SPFA(1,1);
        SPFA(2,2);
        int min=inf;
        for(int i=0;i<M;i++)
        {
            if(mark[mypoint[i].from]!=mark[mypoint[i].to])
             {
                 if(dis[mypoint[i].from]+dis[mypoint[i].to]+mypoint[i].val<min)
                 {
                     min=dis[mypoint[i].from]+dis[mypoint[i].to]+mypoint[i].val;
                 }
             }
        }
        printf("%d\n",min);
    }
    return 0;
}

  

  

 

 

posted on 2011-08-18 21:34  _Clarence  阅读(193)  评论(0编辑  收藏  举报

导航