結果
| 問題 |
No.19 ステージの選択
|
| ユーザー |
simezi_tan
|
| 提出日時 | 2015-07-22 20:10:18 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 2,850 bytes |
| コンパイル時間 | 1,599 ms |
| コンパイル使用メモリ | 166,004 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-12-23 10:03:24 |
| 合計ジャッジ時間 | 2,066 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 24 |
ソースコード
#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;
typedef int weight;
typedef vector<weight> Array;
typedef vector<Array> matrix;
void backward_traverse(int v, int s, int r, matrix &g,
vector<int> &no, vector< vector<int> > &comp,
vector<int> &prev, vector<weight> &mcost,
vector<int> &mark, weight &cost, bool &found) {
const int n = g.size();
if (mark[v]) {
vector<int> temp = no;
found = true;
do {
cost += mcost[v];
v = prev[v];
if (v != s) {
while (comp[v].size() > 0) {
no[comp[v].back()] = s;
comp[s].push_back(comp[v].back());
comp[v].pop_back();
}
}
} while (v != s);
for (int j = 0; j < n; ++j)
if (j != r && no[j] == s)
for (int i = 0; i < n; ++i)
if (no[i] != s && g[i][j] < inf)
g[i][j] -= mcost[ temp[j] ];
}
mark[v] = true;
for (int i = 0; i < n; ++i)
if (no[i] != no[v] && prev[ no[i] ] == v)
if (!mark[ no[i] ] || i == s)
backward_traverse(i, s, r, g,
no, comp, prev, mcost, mark, cost, found);
}
weight minimum_spanning_arborescence(int r, matrix &g) {
const int n = g.size();
vector<int> no(n);
vector< vector<int> > comp(n);
for (int i = 0; i < n; ++i) {
no[i] = i;
comp[i].push_back(i);
}
weight cost = 0;
while (1) {
vector<int> prev(n, -1);
vector<weight> mcost(n, inf);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (j == r) continue;
if (no[i] != no[j] && g[i][j] < inf) {
if (g[i][j] < mcost[ no[j] ]) {
mcost[ no[j] ] = g[i][j];
prev[ no[j] ] = no[i];
}
}
}
}
bool stop = true;
vector<int> mark(n);
for (int i = 0; i < n; ++i) {
if (i == r || mark[i] || comp[i].size() == 0) continue;
bool found = false;
backward_traverse(i, i, r, g,
no, comp, prev, mcost, mark, cost, found);
if (found) stop = false;
}
if (stop) {
for (int i = 0; i < n; ++i)
if (prev[i] >= 0)
cost += mcost[i];
return cost;
}
}
}
int main(){
int n, l[100], s[100];
cin >> n;
rep(i, n) cin >> l[i] >> s[i], s[i]--;
vector<vi> m(n + 1, vi(n + 1, inf));
rep(i, n) m[n][i] = l[i] * 2;
rep(i, n) m[s[i]][i] = l[i];
//rep(i, 1 + n) rep(j, n + 1) cerr<<m[i][j]<<(j==n?"\n":" ");
printf("%.1f\n", minimum_spanning_arborescence(n, m) / 2.0);
return 0;
}
simezi_tan