3767 I Wanna Go Home

問題概要

重み付き無向グラフで表わされる都市と道路がある。
都市1から都市2へ最短距離で帰りたい。

この国では内戦がおきて、それぞれの都市はリーダー1またはリーダー2のどちらかを支持している。
安全のために、リーダーの異なる都市への移動は一度だけにしたい。
また、都市1のリーダーは1、都市2のリーダーは2であることがわかっている。


移動しなければならない距離を求めよ。
条件を満たして都市1から都市2へ帰ることができないとき、-1を出力せよ。

解法

リーダーが違う都市間の移動は最大1回、
かつ出発の都市はリーダー1で、到着の都市はリーダー2であるため、
一度1から2の都市に移動したら2から1の都市へ戻ることはできないことがわかる。


すなわち、元のグラフで2->1の辺はすべて削除した上でダイクストラ法をすれば良い。

ソースコード

int n,m,l[600];
int a[10000],b[10000],c[10000];
vector<vector<pair<int,int> > > e;

int func(){
	bool v[600]={0};
	priority_queue<pair<int,int> > Q; Q.push(mp(0,0));
	while(!Q.empty()){
		int c=Q.top().second,cc=Q.top().first; Q.pop();
		if(v[c])continue;
		v[c]=1; if(c==1)return -cc;
		
		fr(i,e[c])if(!v[i->first])Q.push(mp(cc-i->second,i->first));
	}
	return -1;
}
int main(){
	while(scanf("%d",&n),n){
		e.clear(); e.resize(n);
		scanf("%d",&m);
		rep(i,m)scanf("%d%d%d",a+i,b+i,c+i);
		rep(i,n)scanf("%d",l+i);
		
		rep(i,m){
			int x=a[i]-1,y=b[i]-1,z=c[i];
			if(l[x]!=l[y]){
				if(l[x]==2)swap(x,y);
				e[x].pb(mp(y,z));
			}
			else e[x].pb(mp(y,z)),e[y].pb(mp(x,z));
		}
		printf("%d\n",func());
	}
	return 0;
}