A:签到,从左往右走一遍判断下有没有遇到t即可
B:先利用floyd求出传递闭包,然后利用这个传递闭包贪心小的尽量往前放即可
C:贪心的策略,放的顺序其实根据拿的顺序就可以确定的,所以只要在拿的顺序上从左往右扫一遍即可
D:先DFS预处理出每条边两边点的个数,然后三元组对于每个边经过都是n - 2次,所以一个边都会被计算到n - 2 * 一边点 * 另一边点个数
代码:
#include <cstdio> #include <cstdlib> const int N = 30005; int n, t, a[N]; int main() { scanf("%d%d", &n, &t); for (int i = 1; i <= n - 1; i++) scanf("%d", &a[i]); int bo = 0; for (int i = 1; i <= t;) { if (i == t) { bo = 1; break; } i += a[i]; } printf("%s\n", bo ? "YES" : "NO"); return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 305; int n, a[N], g[N][N], vis[N]; char str[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n; i++) { scanf("%s", str); for (int j = 0; j < n; j++) g[i][j] = str[j] - '0'; g[i][i] = 1; } for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { g[i][j] |= (g[i][k]&g[k][j]); } } } for (int i = 0; i < n; i++) { int Min = n; for (int j = 0; j < n; j++) { if (g[j][i] && !vis[a[j]]) { Min = min(Min, a[j]); } } vis[Min] = 1; printf("%d ", Min); } return 0; }
#include <cstdio> #include <cstring> const int N = 505; typedef long long ll; int n, m, w[N], vis[N][N]; int v; ll sum = 0; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &w[i]); for (int i = 1; i <= m; i++) { scanf("%d", &v); for (int j = 1; j <= n; j++) sum += w[j] * vis[v][j]; memset(vis[v], 0, sizeof(vis[v])); for (int j = 1; j <= n; j++) { if (v == j) continue; vis[j][v] = 1; } } printf("%lld\n", sum); return 0; }
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int N = 100005; int n; struct Edge { int u, v, id, num; double len; Edge(){} Edge(int u, int v, int id) { this->u = u; this->v = v; this->id = id; } } e[N]; vector<Edge> g[N]; int dfs(int u, int p) { int sz = 1; for (int i = 0; i < g[u].size(); i++) { int v = g[u][i].v; if (v == p) continue; int tmp = dfs(v, u); sz += tmp; e[g[u][i].id].num = tmp; } return sz; } int main() { scanf("%d", &n); int u, v; double w; for (int i = 1; i <= n - 1; i++) { scanf("%d%d%lf", &u, &v, &w); e[i].len = w; g[u].push_back(Edge(u, v, i)); g[v].push_back(Edge(v, u, i)); } dfs(1, 0); int q; scanf("%d", &q); int id, vv; double sum = 0; for (int i = 1; i <= n - 1; i++) { sum += (double)(n - 2) * (e[i].num) * (n - e[i].num) * (e[i].len); } double c1 = (double)n * (n - 1) * (n - 2) / 2 / 3; while (q--) { scanf("%d%d", &id, &vv); sum -= (double)(n - 2) * (e[id].num) * (n - e[id].num) * (e[id].len - vv); e[id].len = vv; printf("%.10lf\n", sum / c1); } return 0; }
原文:http://blog.csdn.net/accelerator_/article/details/42302449