মান लीजिए हमारे पास costs_from এবং costs_to নামে একই আকারের দুটি তালিকা রয়েছে, যেখানে প্রতিটি সূচক i একটি শহরকে প্রতিনিধিত্ব করে। শহর i থেকে শহর j পর্যন্ত একমুখী সড়ক তৈরির খরচ হবে costs_from[i] + costs_to[j]। আমাদের কাছে একটি এজ লিস্টও আছে যেখানে প্রতিটি এজ [x, y] নির্দেশ করে যে শহর x থেকে শহর y পর্যন্ত ইতিমধ্যে একটি একমুখী সড়ক রয়েছে। যদি আমরা শহর ০ থেকে যেকোনো শহরে যেতে চাই, তবে প্রয়োজনীয় সড়কগুলো নির্মাণের ন্যূনতম খরচ বের করতে হবে।
উদাহরণ
ইনপুট: costs_from = [6, 2, 2, 12], costs_to = [2, 2, 3, 2], edges = [[0, 3]]
আউটপুট: 13
ব্যাখ্যা: আমরা ০ থেকে ২ নম্বর শহরে যেতে পারি ৯ খরচে (৬+৩)। তারপর ২ থেকে ১ নম্বর শহরে যেতে পারি ৪ খরচে (২+২)। এবং ০ থেকে ৩ নম্বর শহরে যাওয়ার সড়ক ইতিমধ্যে আছে। মোট খরচ = ৯ + ৪ = ১৩।
সমাধানের ধাপসমূহ
n := costs_fromএর আকারret := 0- দুটি ম্যাপ সংজ্ঞায়িত করুন:
edgesএবংredges - প্রতিটি
itএজের জন্যg-তে:edges[it[0]]-এit[1]যোগ করুনredges[it[1]]-এit[0]যোগ করুন
from_cost := infinity- দুটি সেট সংজ্ঞায়িত করুন:
visitedএবংreachable dfs(i)ফাংশন সংজ্ঞায়িত করুন:- যদি
iভিজিট না করা হয় এবংreachable-এ না থাকে:i-কেvisited-এ যোগ করুন- প্রতিটি
jedges[i]-তে:dfs(j)কল করুন i-কেpoঅ্যারেতে যোগ করুন
- যদি
dfs2(i)ফাংশন সংজ্ঞায়িত করুন:- যদি
iভিজিট করা হয়:trueফেরত দিন - যদি
ireachable-এ থাকে:falseফেরত দিন i-কে ভিজিট এবংreachableহিসেবে চিহ্নিত করুনret := true- প্রতিটি
jredges[i]-তে:ret := ret AND dfs2(j) retফেরত দিন
- যদি
- একটি কিউ
qসংজ্ঞায়িত করুন 0-কেreachableএবংq-এ যোগ করুন- যখন
qখালি না হয়:node := q-র প্রথম উপাদানq-র থেকে উপাদান মুছুন- প্রতিটি
iedges[node]-তে:- যদি
ireachable-এ না থাকে:i-কেreachableএবংq-এ যোগ করুন
- যদি
from_cost := min(from_cost, costs_from[node])
global_min := costs_from-এর ন্যূনতম উপাদানret := ret + from_cost - global_min- একটি অ্যারে
poসংজ্ঞায়িত করুন i = 0থেকেnপর্যন্ত:dfs(i)কল করুনpoঅ্যারে উল্টে দিন- প্রতিটি
ipo-তে:- যদি
ireachable-এ থাকে: পরবর্তী ইটেরেশনে যান visitedঅ্যারে ক্লিয়ার করুনinitial := dfs2(i)- যদি
initialসত্য হয়:best := infinity- প্রতিটি
jvisited-তে:best := min(best, costs_to[j]) ret := ret + global_min + best
- যদি
retফেরত দিন
C++ বাস্তবায়ন
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int solve(vector<int>& costs_from, vector<int>& costs_to, vector<vector<int>>& g) {
int n = costs_from.size();
int ret = 0;
map<int, vector<int>> edges;
map<int, vector<int>> redges;
for (auto& it : g) {
edges[it[0]].push_back(it[1]);
redges[it[1]].push_back(it[0]);
}
int from_cost = INT_MAX;
set<int> visited;
set<int> reachable;
queue<int> q;
reachable.insert(0);
q.push(0);
while (!q.empty()) {
int node = q.front();
q.pop();
for (int i : edges[node]) {
if (!reachable.count(i)) {
reachable.insert(i);
q.push(i);
}
}
from_cost = min(from_cost, costs_from[node]);
}
int global_min = *min_element(costs_from.begin(), costs_from.end());
ret += from_cost - global_min;
vector<int> po;
function<void(int)> dfs;
dfs = [&](int i) {
if (!visited.count(i) && !reachable.count(i)) {
visited.insert(i);
for (int j : edges[i]) {
dfs(j);
}
po.push_back(i);
}
};
for (int i = 0; i < n; i++) dfs(i);
reverse(po.begin(), po.end());
function<bool(int)> dfs2;
dfs2 = [&](int i) {
if (visited.count(i)) return true;
if (reachable.count(i)) return false;
visited.insert(i);
reachable.insert(i);
bool ret = true;
for (int j : redges[i]) {
ret &= dfs2(j);
}
return ret;
};
for (int i : po) {
if (reachable.count(i)) continue;
visited.clear();
bool initial = dfs2(i);
if (initial) {
int best = INT_MAX;
for (int j : visited) {
best = min(best, costs_to[j]);
}
ret += global_min + best;
}
}
return ret;
}
};
int solve(vector<int>& costs_from, vector<int>& costs_to, vector<vector<int>>& edges) {
return (new Solution())->solve(costs_from, costs_to, edges);
}
int main() {
vector<int> costs_from = {6, 2, 2, 12};
vector<int> costs_to = {2, 2, 3, 2};
vector<vector<int>> edges = {{0, 3}};
cout << solve(costs_from, costs_to, edges);
return 0;
}
ইনপুট
{6, 2, 2, 12}, {2, 2, 3, 2}, {{0, 3}}
আউটপুট
13