7-7 家庭房产
#include <bits/stdc++.h>
const int N = 1e5 + 10;
using namespace std;
int p[N], si[N], sum[N], area[N], n;
bool st[N];
struct node {
int id, si;
double sum, area;
};
bool cmp(node a, node b) {
if (a.area == b.area) return a.id < b.id;
return a.area > b.area;
}
int find(int x) {
if (x == p[x]) return x;
return p[x] = find(p[x]);
}
void merge(int a, int b) {
a = find(a), b = find(b);
if (a != b) {
if (a < b) swap(a, b);
p[a] = b;
si[b] += si[a];
sum[b] += sum[a];
area[b] += area[a];
}
}
int main() {
cin >> n;
for (int i = 0; i <= 1e5; i++) {
p[i] = i;
si[i] = 1;
}
for (int i = 1; i <= n; i++) {
int x, f, m, k;
cin >> x >> f >> m;
st[x] = 1;
if (f != -1) st[f] = 1, merge(x, f);
if (m != -1) st[m] = 1, merge(x, m);
cin >> k;
while (k--) {
int id;
cin >> id;
st[id] = 1;
merge(x, id);
}
cin >> f >> m;
sum[find(x)] += f;
area[find(x)] += m;
}
vector<node> res;
for (int i = 0; i <= 1e5; i++) {
if (st[i] && find(i) == i) {
res.push_back({i, si[i], sum[i] / (si[i] * 1.0), area[i] / (si[i] * 1.0)});
}
}
sort(res.begin(), res.end(), cmp);
cout << res.size() << endl;
for (int i = 0 ; i < res.size() ; i++) {
node it = res[i];
printf("%04d %.d %.3f %.3f\n", it.id, it.si, it.sum, it.area);
}
}
7-8 森森美图
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 1e9
const int N = 110;
using namespace std;
typedef pair<int, int> PII;
int X1, Y1, X2, Y2;
int n, m, flag = 1;
int g[N][N];
double dist[N][N];
int dx[] = {-1, 1, -1, 1, 1, -1, 0, 0}, dy[] = {-1, 1, 1, -1, 0, 0, 1, -1};
bool check1(int x, int y) {
double t = (X2 - X1) * (y - Y1) - (Y2 - Y1) * (x - X1);
if (flag * t > 0 || x == X2 && y == Y2) return true;
return false;
}
bool check2(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
double bfs() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
dist[i][j] = INF;
}
}
queue<PII> q;
dist[X1][Y1] = g[X1][Y1];
q.push({X1, Y1});
while (q.size()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 8; i++) {
int x = t.first + dx[i], y = t.second + dy[i];
if (check2(x, y) && check1(x, y)) {
double w = g[x][y];
if (i < 4) w += (sqrt(2) - 1) * (g[t.first][t.second] + g[x][y]);
if (dist[x][y] > dist[t.first][t.second] + w) {
dist[x][y] = dist[t.first][t.second] + w;
q.push({x, y});
}
}
}
}
flag = -1;
return dist[X2][Y2];
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> g[i][j];
}
}
cin >> Y1 >> X1 >> Y2 >> X2;
printf("%.2f", bfs() + bfs() - g[X1][Y1] - g[X2][Y2]);
}
7-9 哥尼斯堡的“七桥问题”
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
const int N = 1e3 + 10;
using namespace std;
int du[N], p[N];
int find(int x) {
if (x == p[x]) return x;
return p[x] = find(p[x]);
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> v(n + 1);
for (int i = 1; i <= n; i++) {
p[i] = i;
}
while (m--) {
int a, b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
a = find(a), b = find(b);
if (a != b) p[a] = b;
}
int res = 1;
for (int i = 1; i <= n; i++) {
if (find(i) != find(1) || v[i].size() && v[i].size() & 1) {
res = 0;
break;
}
}
cout << res;
}
7-10 公路村村通
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 100010, M = 200010, INF = 0x3f3f3f3f;
int n, m;
int p[N];
struct Edge {
int a, b, w;
bool operator<(const Edge &W) const { return w < W.w; }
} edges[M];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void kruskal() {
sort(edges, edges + m);
for (int i = 1; i <= n; i++) p[i] = i;
int res = 0, cnt = 0;
for (int i = 0; i < m; i++) {
int a = edges[i].a, b = edges[i].b, w = edges[i].w;
a = find(a), b = find(b);
if (a != b) {
p[a] = b;
res += w;
cnt++;
}
}
if (cnt < n - 1) puts("-1");
else cout << res;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
edges[i] = {a, b, w};
}
kruskal();
return 0;
}
7-11 旅游规划
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 0x3f3f3f3f
const int N = 1e4 + 10, M = 1e7 + 10;
using namespace std;
int h[N], e[M], w1[M], w2[M], ne[M], idx;
int dist[N], cost[N];
bool st[N];
int n, m, S, T;
void add(int a, int b, int c, int d) {
e[idx] = b;
w1[idx] = c;
w2[idx] = d;
ne[idx] = h[a];
h[a] = idx++;
}
void spfa() {
memset(dist, 0x3f, sizeof dist);
dist[S] = cost[S] = 0;
queue<int> q;
q.push(S);
st[S] = true;
while (q.size()) {
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[t] + w1[i]) {
dist[j] = dist[t] + w1[i];
cost[j] = cost[t] + w2[i];
if (!st[j]) {
q.push(j);
st[j] = true;
}
}
if (dist[j] == dist[t] + w1[i]) {
cost[j] = min(cost[j], cost[t] + w2[i]);
}
}
}
cout << dist[T] << ' ' << cost[T];
}
int main() {
cin >> n >> m >> S >> T;
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
add(a, b, c, d);
add(b, a, c, d);
}
spfa();
}
7-12 关键活动
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
const int N = 1e5 + 10;
using namespace std;
int du[N];
int t1[N], t2[N];
queue<int> q;
vector<int> res;
struct node {
int e, w;
};
int main() {
int n, m;
cin >> n >> m;
vector<vector<node>> v(n + 1);
while (m--) {
int a, b, c;
cin >> a >> b >> c;
v[a].push_back({b, c});
du[b]++;
}
for (int i = 1; i <= n; i++) {
if (du[i] == 0) {
q.push(i);
res.push_back(i);
}
}
while (q.size()) {
int t = q.front();
q.pop();
for (auto it : v[t]) {
int e = it.e, w = it.w;
du[e]--;
if (du[e] == 0) {
q.push(e);
res.push_back(e);
}
t1[e] = max(t1[e], t1[t] + w);
}
}
if (res.size() != n)
puts("0");
else {
int ans = 0;
for (int i = 1; i <= n; i++) {
ans = max(ans, t1[i]);
}
fill(t2 + 1, t2 + 1 + n, ans);
for (int i = res.size() - 1; i >= 0; i--) {
int j = res[i];
for (auto it : v[j]) {
int e = it.e, w = it.w;
t2[j] = min(t2[j], t2[e] - w);
}
}
cout << ans << endl;
for (int i = 1; i <= n; i++) {
for (int j = v[i].size() - 1; j >= 0; j--) {
int e = v[i][j].e, w = v[i][j].w;
if (t1[i] + w == t2[e]) {
cout << i << "->" << e << endl;
}
}
}
}
}
7-13 任务调度的合理性
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
const int N = 1e5 + 10;
using namespace std;
int du[N];
int dist[N];
unordered_map<int, int> pre;
int main() {
int n;
cin >> n;
vector<vector<int>> v(n + 1);
for (int i = 1; i <= n; i++) {
int k, x;
cin >> k;
du[i] = k;
while (k--) {
cin >> x;
v[x].push_back(i);
}
}
queue<int> q;
vector<int> res;
for (int i = 1; i <= n; i++) {
if (du[i] == 0) {
q.push(i);
res.push_back(i);
}
}
while (q.size()) {
int t = q.front();
q.pop();
for (auto it : v[t]) {
du[it]--;
if (du[it] == 0) {
q.push(it);
res.push_back(it);
}
}
}
if (res.size() != n)
puts("0");
else
puts("1");
}
7-14 最短工期
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
const int N = 1e5 + 10;
using namespace std;
int du[N];
int dist[N];
struct node {
int e, w;
};
int main() {
int n, m;
cin >> n >> m;
vector<vector<node>> v(n);
while (m--) {
int a, b, c;
cin >> a >> b >> c;
v[a].push_back({b, c});
du[b]++;
}
queue<int> q;
int res = 0;
for (int i = 0; i < n; i++) {
if (du[i] == 0) {
q.push(i);
for (auto j : v[i]) {
dist[j.e] = max(dist[j.e], dist[i] + j.w);
}
res++;
}
}
while (q.size()) {
int t = q.front();
q.pop();
for (auto it : v[t]) {
du[it.e]--;
if (du[it.e] == 0) {
q.push(it.e);
for (auto j : v[it.e]) {
dist[j.e] = max(dist[j.e], dist[it.e] + j.w);
}
res++;
}
}
}
if (res != n)
puts("Impossible");
else {
int ans = 0;
for (int i = 0; i < n; i++) {
ans = max(ans, dist[i]);
}
cout << ans;
}
}
7-15 最短路径
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
const int N = 100100, M = N;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
bool st[N];
int S, T;
void add(int a, int b, int c) {
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}
void spfa() {
memset(dist, 0x3f, sizeof dist);
dist[S] = 0;
queue<int> q;
q.push(S);
st[S] = true;
while (q.size()) {
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[t] + w[i]) {
dist[j] = dist[t] + w[i];
if (!st[j]) {
q.push(j);
st[j] = true;
}
}
}
}
if (dist[T] > 1e8)
printf("There is no path between %d and %d.", S, T);
else
printf("The length of the shortest path between %d and %d is %d.\n", S,
T, dist[T]);
}
int main() {
memset(h, -1, sizeof h);
int n, m;
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
add(a, b, 1);
add(b, a, 1);
}
cin >> S >> T;
spfa();
}
7-16 最短路径算法(Floyd-Warshall)
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int N = 1100;
int g[N][N];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> g[i][j];
if (i != j && g[i][j] == 0) g[i][j] = 1e9;
}
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (g[i][j] > 1e9 / 2 && i != j) g[i][j] = -1;
cout << g[i][j] << ' ';
}
puts("");
}
}