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;
}