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