結果
| 問題 |
No.1288 yuki collection
|
| コンテスト | |
| ユーザー |
mugen_1337
|
| 提出日時 | 2020-11-28 19:50:33 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,455 bytes |
| コンパイル時間 | 2,636 ms |
| コンパイル使用メモリ | 215,476 KB |
| 最終ジャッジ日時 | 2025-01-16 09:44:41 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 TLE * 5 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
#define ALL(x) begin(x),end(x)
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mod 1000000007
using ll=long long;
const int INF=1000000000;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
struct IOSetup{
IOSetup(){
cin.tie(0);
ios::sync_with_stdio(0);
cout<<fixed<<setprecision(12);
}
} iosetup;
template<typename T>
ostream &operator<<(ostream &os,const vector<T>&v){
for(int i=0;i<(int)v.size();i++) os<<v[i]<<(i+1==(int)v.size()?"":" ");
return os;
}
template<typename T>
istream &operator>>(istream &is,vector<T>&v){
for(T &x:v)is>>x;
return is;
}
template<typename flow_t, typename cost_t>
struct PrimalDual{
struct edge{
int to;
flow_t cap;
cost_t cost;
int rev;//この辺の逆辺がg[from]の何番目にあるか
bool isrev;
};
vector<vector<edge>> graph;
vector<cost_t> potential,min_cost;
vector<int> prevv,preve;//点,辺
const cost_t TINF;
PrimalDual(int V):graph(V),TINF(numeric_limits<cost_t>::max()){}
void add_edge(int from,int to,flow_t cap,cost_t cost){
graph[from].push_back((edge){to,cap,cost,(int)graph[to].size(),false});
graph[to].push_back((edge){from,0,-cost,(int)graph[from].size()-1,true});
}
cost_t min_cost_flow(int s,int t,flow_t f,bool &ok){
int V=(int)graph.size();
cost_t ret=0;
using Pi=pair<cost_t,int>;
priority_queue<Pi,vector<Pi>,greater<Pi>> que;
potential.assign(V,0);
preve.assign(V,-1);
prevv.assign(V,-1);
while(f>0){
min_cost.assign(V,TINF);
que.emplace(0,s);
min_cost[s]=0;
//dijkstraパート
while(!que.empty()){
Pi p=que.top();que.pop();
if(min_cost[p.second]<p.first) continue;
for(int i=0;i<(int)graph[p.second].size();i++){
edge &e=graph[p.second][i];
cost_t nextCost=min_cost[p.second]+e.cost+potential[p.second]-potential[e.to];
if(e.cap>0 and min_cost[e.to]>nextCost){
min_cost[e.to]=nextCost;
prevv[e.to]=p.second,preve[e.to]=i;
que.emplace(min_cost[e.to],e.to);
}
}
}
if(min_cost[t]==TINF){
ok=false;
return ret;
}
// dijkstraの結果に応じてpotentialを調節
for(int v=0;v<V;v++)potential[v]+=min_cost[v];
flow_t addflow=f;
for(int v=t;v!=s;v=prevv[v]){
addflow=min(addflow,graph[prevv[v]][preve[v]].cap);
}
f-=addflow;
ret+=addflow*potential[t];
for(int v=t;v!=s;v=prevv[v]){
edge &e=graph[prevv[v]][preve[v]];
e.cap-=addflow;
graph[v][e.rev].cap+=addflow;
}
}
ok=true;
return ret;
}
void output(){
for(int i=0;i<graph.size();i++){
for(auto &e:graph[i]){
if(e.isrev)continue;
auto &rev_e=graph[e.to][e.rev];
cout<<i<<"->"<<e.to<<" (flow: "<<rev_e.cap<<" / "<<rev_e.cap+e.cap<<")"<<endl;
}
}
}
};
signed main(){
int n;cin>>n;
string s;cin>>s;
vector<ll> v(n);
cin>>v;
PrimalDual<ll,ll> flow(2*n+10);
int src=2*n,sink=2*n+1;
rep(i,n){
if(s[i]=='y') flow.add_edge(src,i,1,-v[i]);
if(s[i]=='i') flow.add_edge(i+n,sink,1,0);
flow.add_edge(i,i+n,1,0);
for(int j=i+1;j<n;j++){
if(s[i]=='y' and s[j]=='u') flow.add_edge(i+n,j,1,-v[j]);
if(s[i]=='u' and s[j]=='k') flow.add_edge(i+n,j,1,-v[j]);
if(s[i]=='k' and s[j]=='i') flow.add_edge(i+n,j,1,-v[j]);
}
}
flow.add_edge(src,sink,2*n,0);
bool ok;
cout<<-flow.min_cost_flow(src,sink,n,ok)<<endl;
return 0;
}
mugen_1337