2135-Reverse a Road

問題概要

有向グラフが与えられる。
その中の一辺を逆向きに出来るとしたときのST間最短路の長さと逆向きにする辺を答えろ

解法

ダイクストラ
辺を入れかえたか否かと現在の頂点番号を記録する

実装(C++)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
#define REP(i,x)for(int i=0;i<(int)x;i++)
struct Edge{
	int dst,cost;
};
typedef pair<int,int> P;
typedef vector<Edge> Node;
typedef vector<Node> Graph;
int N,M,S,T;
Graph G;
P d[2000][2];
bool used[2000][2];
void dijkstra(int s){
	memset(d,0x3f,sizeof(d));
	memset(used,0,sizeof(used));
	d[s][0]=P(0,0);
	while(1){
		P mincost=P(99999999,99999999);int mi=-1,mj=0;
		for(int i=0;i<N;i++){
			for(int j=0;j<2;j++){
				if(used[i][j]==false&&mincost>d[i][j]){
					mincost=d[i][j];
					mi=i;mj=j;
				}
			}
		}
		if(mi==-1)break;
		used[mi][mj]=true;
		REP(i,G[mi].size()){
			Edge &e=G[mi][i];
			if(e.cost>0&&mj==0&&mincost.second==0){
				d[e.dst][1]=min(d[e.dst][1],P(mincost.first+1,e.cost));
			}
			if(e.cost==0){
				d[e.dst][mj]=min(d[e.dst][mj],P(mincost.first+1,mincost.second));
			}
		}
	}
}
int main() {
	while(~scanf("%d",&N)){
		if(N==0)break;
		scanf("%d%d%d",&S,&T,&M);S--;T--;
		G=Graph(N);
		for(int i=0;i<M;i++){
			int a,b;
			scanf("%d%d",&a,&b);a--;b--;
			G[a].push_back((Edge){b,0});
			G[b].push_back((Edge){a,i+1});
		}
		dijkstra(S);
		if(d[T][0].first>d[T][1].first){
			cout<<d[T][1].first<<" "<<d[T][1].second<<endl;
		}else{
			cout<<d[T][0].first<<" "<<0<<endl;
		}
	}
}