結果
| 問題 |
No.1678 Coin Trade (Multiple)
|
| コンテスト | |
| ユーザー |
mugen_1337
|
| 提出日時 | 2021-09-10 21:55:13 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,354 bytes |
| コンパイル時間 | 2,460 ms |
| コンパイル使用メモリ | 207,600 KB |
| 最終ジャッジ日時 | 2025-01-24 10:24:42 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 30 WA * 1 TLE * 25 |
ソースコード
#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;}
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;
}
// https://ei1333.github.io/library/graph/flow/primal-dual.hpp
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,K;cin>>N>>K;
PrimalDual<int,int> flow(N+N+40);
int src=N+N,sink=N+N+1;
flow.add_edge(src,0,K,0);
flow.add_edge(N+N-1,sink,K,0);
rep(i,N){
flow.add_edge(i,i+N,K,0);
if(i+1<N) flow.add_edge(i+N,i+1,K,0);
}
vector<int> A(N);
rep(i,N){
int t;cin>>A[i]>>t;
rep(j,t){
int a;cin>>a;a--;
flow.add_edge(a+N,i,1,-(A[i]-A[a]));
}
}
flow.add_edge(src,sink,INF,0);
bool ok=false;
int mx=K*N;
int res=flow.min_cost_flow(src,sink,mx,ok);
cout<<-res<<endl;
return 0;
}
mugen_1337