Submission #1130765

#TimeUsernameProblemLanguageResultExecution timeMemory
1130765ChuanChenCommuter Pass (JOI18_commuter_pass)C++20
100 / 100
704 ms40044 KiB
/* grafo direcionado dos caminho minimo de S->T é uma dag S: ing = 0 T : outg = 0 dp no DAG dpU(i) = custo de U até i dpV(i) = custo de i até V repita pro DAG de T->S */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int lim = 1e5+5; const ll inf = 1e18; int n, m, S, T, U, V; ll ans = inf; //ARESTAS struct Edge{ int a, b, c; bool in_path; }; vector<Edge> edges; vector<int> adj[lim], weight[lim]; void addEdge(int a, int b, int c){ edges.push_back({a, b, c, false}); adj[a].push_back(b); adj[b].push_back(a); weight[a].push_back(c); weight[b].push_back(c); } //DIJK FOR MIN_PATHS ll d[4][lim]; //d[0]: S->all, d[1]: T->all, d[2]: U->all, d[3]: V->all void dijk(int r){ set<pair<ll, int>> can; for(int i = 1; i <= n; i++) d[r][i] = inf; if(r == 0) d[r][S] = 0; else if(r == 1) d[r][T] = 0; else if(r == 2) d[r][U] = 0; else if(r == 3) d[r][V] = 0; for(int i = 1; i <= n; i++) can.emplace(d[r][i], i); while(!can.empty()){ int no = can.begin()->second; can.erase(can.begin()); for(int i = 0; i < adj[no].size(); i++){ int v = adj[no][i], p = weight[no][i]; if(d[r][v] > d[r][no] + p){ can.erase({d[r][v], v}); d[r][v] = d[r][no] + p; can.emplace(d[r][v], v); } } } } //DAGs vector<int> dag[2][lim]; //dag[0] for S, dag[1] for T ll dpU[2][lim], dpV[2][lim]; // 0 for S, 1 for T // dpU(i) = custo de U até i // dpV(i) = custo de i até V int ing[2][lim]; void solve(int r){ queue<int> can; for(int i = 1; i <= n; i++){ if(ing[r][i] == 0) can.push(i); } while(!can.empty()){ int no = can.front(); can.pop(); dpU[r][no] = min(dpU[r][no], d[2][no]); dpV[r][no] = min(dpV[r][no], d[3][no]); if(dag[r][no].empty()) continue; for(int v : dag[r][no]){ ing[r][v]--; if(ing[r][v] == 0) can.push(v); if(r == 0){ dpU[0][v] = min(dpU[0][v], dpU[0][no]); dpV[1][v] = min(dpV[1][v], dpV[1][no]); } else{ dpU[1][v] = min(dpU[1][v], dpU[1][no]); dpV[0][v] = min(dpV[0][v], dpV[0][no]); } } } } int main(){ cin.tie(0)->sync_with_stdio(0); if(fopen("in", "r")){ freopen("in", "r", stdin); freopen("out", "w", stdout); freopen("err", "w", stderr); } cin >> n >> m; cin >> S >> T >> U >> V; for(int i = 1; i <= m; i++){ int a, b, c; cin >> a >> b >> c; addEdge(a, b, c); } dijk(0); dijk(1); for(Edge &e : edges){ if(d[0][e.a] + e.c + d[1][e.b] == d[0][T]){ dag[0][e.a].push_back(e.b); ing[0][e.b]++; dag[1][e.b].push_back(e.a); ing[1][e.a]++; } if(d[0][e.b] + e.c + d[1][e.a] == d[0][T]){ dag[1][e.a].push_back(e.b); ing[1][e.b]++; dag[0][e.b].push_back(e.a); ing[0][e.a]++; } } dijk(2); dijk(3); for(int i = 1; i <= n; i++) dpU[0][i] = dpV[0][i] = dpU[1][i] = dpV[1][i] = inf; solve(0); solve(1); ans = d[2][V]; // cout << d[2][V] << '\n'; for(int i = 1; i <= n; i++){ // cerr << "Para i = " << i << '\n'; // cerr << "Caminho S->T: " << dpU[0][i] << " + " << dpV[0][i] << '\n'; // cerr << "Caminho T->S: " << dpU[1][i] << " + " << dpV[1][i] << '\n'; ans = min({ans, dpU[0][i]+dpV[0][i], dpU[1][i]+dpV[1][i]}); } cout << ans << '\n'; } /* 0 -> antes de entrar CP 1 -> dentro do CP na direçao S->T 2 -> dentro do CP na direçao T->S 3 -> depois de sair CP v - w com custo c (v, 0) -> (w, 0) custo c (v, 0) -> (w, 1) custo c se in_path(w) (v, 0) -> (w, 2) custo c se in_path(w) (v, 1) -> (w, 1) com custo 0 se can_go(S, v, w) (v, 1) -> (w, 3) com custo c se in_path(v) (v, 2) -> (w, 2) com custo 0 se can_go(T, v, w) (v, 2) -> (w, 3) com custo 0 se in_path(v) (v, 3) -> (w, 3) com custo c */

Compilation message (stderr)

commuter_pass.cpp: In function 'int main()':
commuter_pass.cpp:106:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  106 |                 freopen("in", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~
commuter_pass.cpp:107:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  107 |                 freopen("out", "w", stdout);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~
commuter_pass.cpp:108:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  108 |                 freopen("err", "w", stderr);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...