kmjp's blog

競技プログラミング参加記です

yukicoder : No.2387 Yokan Factory

これは割とすんなり。
https://yukicoder.me/problems/no/2387

問題

N点M辺のグラフが与えられる。
各辺は、幅と時間が与えられる。
辺をたどって移動するとき、自身の大きさ以上の幅の辺のみ通ることができるとする。
1番の点からN番の点に時間X以下で移動できる、最大の大きさはいくらか。

解法

大きさを二分探索し、あとはダイクストラ法で時間を求めればよい。

int N,M;
ll X;
vector<vector<int>> E[202020];
ll dp[202020];

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	cin>>N>>M>>X;
	FOR(i,M) {
		cin>>x>>y>>j>>k;
		E[x-1].push_back({y-1,j,k});
		E[y-1].push_back({x-1,j,k});
	}
	ll ret=-1;
	for(i=59;i>=0;i--) {
		ll cand=ret+(1LL<<i);
		FOR(j,N) dp[j]=1LL<<60;
		dp[0]=0;
		priority_queue<pair<ll,int>> Q;
		Q.push({0,0});
		while(Q.size()) {
			ll co=-Q.top().first;
			int cur=Q.top().second;
			Q.pop();
			if(dp[cur]!=co) continue;
			FORR(e,E[cur]) if(e[2]>=cand&&dp[e[0]]>co+e[1]) {
				dp[e[0]]=co+e[1];
				Q.push({-dp[e[0]],e[0]});
			}
		}
		if(dp[N-1]<=X) ret=cand;
	}
	cout<<ret<<endl;
}

まとめ

★2.5でもいいのかも?