Submission #1035406

#TimeUsernameProblemLanguageResultExecution timeMemory
1035406CSQ31Board Game (JOI24_boardgame)C++17
100 / 100
1743 ms85900 KiB
#pragma GCC optimize("Ofast") #include<bits/stdc++.h> using namespace std; #define pb push_back #define fi first #define se second #define sz(a) (int)(a.size()) #define all(a) a.begin(),a.end() #define lb lower_bound #define ub upper_bound #define owo ios_base::sync_with_stdio(0);cin.tie(0); #define debug(...) fprintf(stderr, __VA_ARGS__),fflush(stderr) #define time__(d) for(long blockTime = 0; (blockTime == 0 ? (blockTime=clock()) != 0 : false);\ debug("%s time : %.4fs\n", d, (double)(clock() - blockTime) / CLOCKS_PER_SEC)) typedef long long int ll; typedef long double ld; typedef pair<ll,ll> PII; typedef pair<int,int> pii; typedef vector<vector<int>> vii; typedef vector<vector<ll>> VII; ll gcd(ll a,ll b){if(!b)return a;else return gcd(b,a%b);} const int MAXN = 5e4+50; vector<int>adj[MAXN]; ll ans[MAXN]; ll dp[200][MAXN]; int main() { int n,m,k; cin>>n>>m>>k; for(int i=0;i<n;i++)ans[i] = 1e18; for(int i=0;i<m;i++){ int u,v; cin>>u>>v; u--; v--; adj[u].pb(v); adj[v].pb(u); } string s; cin>>s; vector<int>T(k); for(int i=0;i<k;i++){cin>>T[i];T[i]--;} vector<ll>rdist(n,1e9),bdist(n,1e9),ndist(n,1e9),ones; deque<int>q; if(true){ queue<int>q; q.push(T[0]); vector<ll>d(n,n); d[T[0]] = 0; while(!q.empty()){ int v = q.front(); q.pop(); ndist[v] = ans[v] = d[v]; if(v != T[0] && s[v] == '1'){ ones.pb(v); continue; } for(int x:adj[v]){ if(d[x] > d[v]+1){ d[x] = d[v]+1; q.push(x); } } } } for(int i=0;i<n;i++){ if(s[i] == '0')continue; int cnt = 0; for(int x:adj[i])cnt += s[x]=='1'; if(cnt){ rdist[i] = 0; q.pb(i); } } while(!q.empty()){ int v = q.front(); q.pop_front(); for(int x:adj[v]){ if(rdist[x] == 1e9){ if(s[x] == '1'){ rdist[x] = rdist[v]; q.push_front(x); }else{ rdist[x] = rdist[v]+1; q.push_back(x); } } } } //min dist to a red node for(int i=0;i<n;i++){if(s[i] == '1')rdist[i]++;} for(int i=0;i<n;i++){ if(s[i] == '1'){ for(int x:adj[i]){ if(bdist[x] > 1){ bdist[x] = 1; q.pb(x); } } } } while(!q.empty()){ int v = q.front(); q.pop_front(); for(int x:adj[v]){ if(bdist[x] == 1e9){ bdist[x] = bdist[v]+1; q.push_back(x); } } } //min dist to a black node // for(int i=0;i<n;i++)cout<<bdist[i]<<" "<<rdist[i]<<'\n'; if(k-1 <= 300){ //half of the sqrt sol ll sum = 0; vector<ll>f; for(int i=1;i<k;i++){ sum += bdist[T[i]]; f.pb(rdist[T[i]] - bdist[T[i]]); } sort(all(f)); for(int i=0;i<k;i++){ ll c = 2*(k-1) - i; vector<ll>dist(n,1e18); priority_queue<PII,vector<PII>,greater<PII>>pq; for(int v:ones){ for(int x:adj[v]){ ll cost = ndist[v] + sum + 1; if(s[x] == '1')cost += c; if(dist[x] > cost){ dist[x] = cost; pq.push({dist[x],x}); } } } while(!pq.empty()){ int v = pq.top().se; ll d = pq.top().fi; pq.pop(); if(d != dist[v])continue; //cout<<v<<" "<<d<<'\n'; for(int x:adj[v]){ if(s[x] == '0'&& dist[x] > d+1){ dist[x] = d+1; pq.push({dist[x],x}); } if(s[x] == '1' && dist[x] > d+c+1){ dist[x] = d+c+1; pq.push({dist[x],x}); } } } for(int j=0;j<n;j++){ //cout<<dist[j]<<" "; if(s[j] == '1')ans[j] = min(ans[j],dist[j]-c); else ans[j] = min(ans[j],dist[j]); } if(i!=k-1)sum+=f[i]; } for(int i=0;i<n;i++)cout<<ans[i]<<'\n'; return 0; } vector<int>stops(n,1e9); stops[T[0]] = 0; q.pb(T[0]); while(!q.empty()){ int v = q.front(); q.pop_front(); for(int x:adj[v]){ if(s[x] == '0' && stops[x] > stops[v]){ stops[x] = stops[v]; q.push_front(x); } if(s[x] == '1' && stops[x] > stops[v]+1){ stops[x] = stops[v]+1; q.pb(x); } } } for(int i=0;i<200;i++){ for(int j=0;j<n;j++)dp[i][j] = 1e18; } dp[0][T[0]] = 0; queue<array<int,3>>qq; qq.push({0,0,T[0]}); while(!qq.empty()){ int v = qq.front()[2]; int len = qq.front()[1]; int num = qq.front()[0]; qq.pop(); //cout<<v<<" "<<len<<" "<<num-stops[v]<<" "<<dp[num-stops[v]][v]<<'\n'; for(int x:adj[v]){ if(s[x] == '0'){ int d = num - stops[x]; if(d < 200 && dp[d][x] > len + 1){ dp[d][x] = len + 1; qq.push({num,len+1,x}); } }else{ int d = num+1 - stops[x]; if(d < 200 && dp[d][x] > len + 1){ dp[d][x] = len + 1; qq.push({num+1,len+1,x}); } } } } vector<ll>cost(n+2,0),inc(n+2,0); for(int i=1;i<k;i++){ int v = T[i]; ll a = bdist[v]; ll b = rdist[v]; cost[1] += min(a,b); //a + 2*(x-1) > b + (x-1) //x >= b-a+1 //x = b-a+1 ll diff = b-a+1; //cout<<v<<" "<<a<<" "<<b<<" "<<diff<<'\n'; if(diff >= 2){ inc[2] += 2; if(diff <= n){ inc[diff] -= 2; cost[diff] -= 2*(diff-2); cost[diff] -= min(a,b); cost[diff] += b + (diff-1); inc[diff+1] ++; } }else inc[2]++; } for(int i=1;i<=n;i++)inc[i] += inc[i-1]; for(int i=1;i<=n;i++)cost[i] += cost[i-1] + inc[i]; //for(int i=0;i<=n;i++)cout<<cost[i]<<" "; // cout<<'\n'; for(int i=0;i<n;i++){ if(i==T[0])continue; ans[i] = 1e18; for(int j=0;j<200;j++){ int len = j + stops[i]; if(s[i] == '1')len--; if(len > n)continue; //cout<<i<<" "<<len<<" "<<dp[j][i]<<" "<<cost[len]<<'\n'; ans[i] = min(ans[i],dp[j][i] + cost[len]); } } for(int i=0;i<n;i++)cout<<ans[i]<<'\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...