閒來無聊在TC上搜羅圖論題目, 無意中發現了這題, 此題構圖其實挺好想,我一開始想的是費用流
後來構完圖才發現是個最小樹形圖。。。 只是覺得div1 lev3的題目不應只有這種程度吧。。。。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class FoxTheLinguist {
public:
int minimalHours(int, vector <string>);
};
typedef int LL;
const LL INF = (int)1e9;
const int N = 105;
const int M = 1005;
struct DMST {
struct Edge {
int u, v;
LL w;
void init(int a, int b, LL c) {
this->u = a, this->v = b, w = c;
}
};
Edge E[M];
LL in[N];
int no[N], pre[N], vis[N];
int n, m, rt;
void init(int n, int r) {
this->n = n;
rt = r;
m = 0;
}
void add(int u, int v, LL w) {
E[m].init(u, v, w);
m++;
}
LL gao() {
LL res = 0;
while (1) {
fill(in, in + n, INF);
for (int i = 0; i < m; i++) {
int u = E[i].u, v = E[i].v;
if (u != v && E[i].w < in[v]) {
in[v] = E[i].w;
pre[v] = u;
}
}
for (int i = 0; i < n; i++) {
if (i == rt) continue;
if (in[i] == INF) return -1;
}
int cnt = 0;
fill(no, no + n, -1);
fill(vis, vis + n, -1);
in[rt] = 0;
for (int i = 0; i < n; i++) {
res += in[i];
int v = i;
while (vis[v] != i && no[v] == -1 && v != rt) {
vis[v] = i;
v = pre[v];
}
if (v != rt && no[v] == -1) {
for (int u = pre[v]; u != v; u = pre[u]) {
no[u] = cnt;
}
no[v] = cnt++;
}
}
if (cnt == 0) break;
for (int i = 0; i < n; i++)
if (no[i] == -1) {
no[i] = cnt++;
}
for (int i = 0; i < m; i++) {
int v = E[i].v;
E[i].u = no[E[i].u];
E[i].v = no[E[i].v];
if (E[i].u != E[i].v)
E[i].w -= in[v];
}
n = cnt;
rt = no[rt];
}
return res;
}
}G;
int FoxTheLinguist::minimalHours(int a, vector<string> info) {
int n = a * 10 + 1;
int s = n - 1;
G.init(n, s);
int m = info.size();
string tmp = "";
for (int i = 0; i < m; i++)
tmp += info[i];
int id = 0;
int sz = tmp.size();
while (id < sz) {
if (tmp[id] == ' ') id++;
int u = (tmp[id] - 'A') * 10 + tmp[1 + id] - '0';
int v = (tmp[4 + id] - 'A') * 10 + tmp[5 + id] - '0';
int w = 0;
for (int j = 7; j <= 10; j++)
w += (tmp[j + id] - '0'), w *= 10;
w /= 10;
G.add(u, v, w);
id += 11;
}
for (int i = 0; i < a; i++)
G.add(s, i * 10, 0);
for (int i = 0; i < a; i++) {
int st = (i + 1) * 10 - 1;
for (int j = 0; j < 9; j++) {
G.add(st, st - 1, 0);
st--;
}
}
return G.gao();
}
<%:testing-code%>
//Powered by [KawigiEdit] 2.0!