結果
| 問題 | No.200 カードファイト! |
| コンテスト | |
| ユーザー |
koyumeishi
|
| 提出日時 | 2015-06-01 23:25:54 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 2,000 ms |
| コード長 | 4,914 bytes |
| コンパイル時間 | 973 ms |
| コンパイル使用メモリ | 91,640 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-10-15 08:59:48 |
| 合計ジャッジ時間 | 1,869 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 26 |
ソースコード
#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <set>
using namespace std;
template<class T>
class Min_Cost_Flow{
public:
struct edge{
int to;
int cap;
T cost;
int rev;
bool reverse;
};
const T INF;
vector<vector<edge>> G;
Min_Cost_Flow(int n, T inf) : G(n), INF(inf){
}
void add_edge(int from, int to, int cap, T cost){
G[from].push_back((edge){to, cap, cost, (int)G[to].size(), false});
G[to].push_back((edge){from, 0, -cost, (int)G[from].size()-1, true});
}
//min cost : s->t (flow:f)
T min_cost_flow(int s, int t, int f){
T cost = 0;
vector<int> prev_v(G.size(),-1);
vector<int> prev_e(G.size(),-1);
vector<T> potantial(G.size(), 0);
vector<T> dist(G.size(), INF);
dist[s] = 0;
/*bellman_ford*/{
bool update = true;
for(int cnt = 0; update; cnt++){
update = false;
for(int i=0; i<G.size(); i++){
if(dist[i] >= INF) continue;
for(int j=0; j<G[i].size(); j++){
if(G[i][j].cap > 0 && dist[G[i][j].to] > dist[i] + G[i][j].cost){
dist[G[i][j].to] = dist[i] + G[i][j].cost;
update = true;
}
}
}
if(update && cnt >= G.size()){
cerr << " there is a negative cycle " << endl;
return -1;
}
cnt++;
}
for(int i=0; i<G.size(); i++){
potantial[i] = dist[i];
}
}
while(f>0){
fill(dist.begin(), dist.end(), INF);
dist[s] = 0;
prev_v[s] = s;
/*dijkstra*/{
priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> pq;
pq.push({0, s});
while(pq.size()){
pair<T, int> p = pq.top(); pq.pop();
if(dist[p.second] < p.first) continue;
dist[p.second] = p.first;
for(int i=0; i<G[p.second].size(); i++){
edge& e = G[p.second][i];
T new_dist = dist[p.second] + e.cost + potantial[p.second] - potantial[e.to];
if(e.cap > 0 && dist[e.to] > new_dist){
dist[e.to] = new_dist;
prev_v[e.to] = p.second;
prev_e[e.to] = i;
pq.push({dist[e.to], e.to});
}
}
}
}
if(potantial[t] + dist[t] == INF){
cerr << "couldn't insert flow f : " << f << endl;
return -1;
}
for(int i=0; i<G.size(); i++){
potantial[i] += dist[i];
}
int d = f;
int pos = t;
while(pos != s){
int v = prev_v[pos];
int e = prev_e[pos];
d = min(d, G[v][e].cap);
pos = prev_v[pos];
}
pos = t;
while(pos != s){
int v = prev_v[pos];
int e = prev_e[pos];
G[v][e].cap -= d;
G[G[v][e].to][G[v][e].rev].cap += d;
pos = v;
}
cost += d * potantial[t]; //potential is new_dist
f -= d;
//f==0 then end
}
return cost;
}
vector<vector<int>> get_edge_info(){
vector<vector<int>> E(G.size());
for(int i=0; i<G.size(); i++){
for(int j=0; j<G[i].size(); j++){
edge& e = G[i][j];
if(e.reverse) continue;
edge& rev_e = G[e.to][e.rev];
if(e.cap == 0){
E[i].push_back(e.to);
}
}
}
return E;
}
};
int main(){
int n;
cin >> n;
int x;
cin >> x;
vector<int> a(x);
for(int i=0; i<x; i++){cin>>a[i];}
random_shuffle(a.begin(), a.end());
int y;
cin >> y;
vector<int> b(y);
for(int i=0; i<y; i++){cin>>b[i];}
random_shuffle(b.begin(), b.end());
int sz_x = (n/x + (n%x==0?0:1)) * x;
int sz_y = (n/y + (n%y==0?0:1)) * y;
int sz = sz_x + sz_y + 2;
int s = sz_x + sz_y + 0;
int t = sz_x + sz_y + 1;
Min_Cost_Flow<int> flow(sz, 1e8);
vector<long long> offset_x;
for(int k=0; k<sz_x/x; k++){
for(int i=0; i<x; i++){
long long cost = 100000 + 10*k;
flow.add_edge(s, i + x*k, 1, cost);
offset_x.push_back(cost);
}
}
vector<long long> offset_y;
for(int k=0; k<sz_y/y; k++){
for(int i=0; i<y; i++){
long long cost = 100000 + 10*k;
flow.add_edge( sz_x + i + y*k, t, 1, cost);
offset_y.push_back(cost);
}
}
for(int i=0; i<sz_x; i++){
for(int j=sz_x; j<sz_x+sz_y; j++){
int l = ( ( (i/x)*x)/y)*y;
int r = (((i/x + 1)*x - 1)/y + 1)*y;
if( j-sz_x < l || r <= j-sz_x) continue;
flow.add_edge( i, j, 1, (a[i%x]>b[(j-sz_x)%y]?0:1) );
}
}
long long ans = 0;
for(int i=0; i<n; i++){
ans -= offset_x[i] + offset_y[i];
}
ans += flow.min_cost_flow(s,t, n);
ans = n - ans;
cout << ans << endl;
/*
cerr << s << " " << t << endl;
auto e = flow.get_edge_info();
map<int, vector<int>> v;
for(int i=0; i<e.size(); i++){
if(i == s || i == t) continue;
if(i >= sz_x) continue;
for(int j=0; j<e[i].size(); j++){
if(e[i][j] == s || e[i][j] == t) continue;
cerr << i << " -> " << e[i][j]-sz_x << " : ";
cerr << a[i%x] << " -> " << b[(e[i][j]-sz_x)%y] << endl;
v[a[i%x]].push_back(b[(e[i][j]-sz_x)%y]);
}
}
for(int i=0; i<x; i++){
cerr << a[i] << " ";
for(auto itr = v[a[i]].begin(); itr != v[a[i]].end(); itr++){
cerr << *itr << " ";
}cerr << endl;
}
*/
return 0;
}
koyumeishi