题解 | #躲避技能#
躲避技能
https://ac.nowcoder.com/acm/contest/40646/A
差不多的想法,但是用的 topo 实现,把出发点标成 1,目标点标成 -1,然后topo网上搞就行,每条边经过的时候加上这条边的边权乘上当前点的值的绝对值。
保龄了,原因是:
char s[105];
scanf ("%s", s);
len = 0; reverse (s, s + strlen (s));
高精度里面的的这个,考场上写成了
char s[105];
scanf ("%s", s);
len = 0; reverse (s, s + len);
看到翻转但完全没用/ll/ll/ll
代码
# include <bits/stdc++.h>
# define wheneveright signed main
using namespace std;
const int maxn = 300005;
const int maxe = 600009;
const int TT = 10000;
struct INT {
int len, a[35];
INT () { len = 0; memset (a, 0, sizeof (a)); }
void get () {
char s[105];
scanf ("%s", s);
len = 0; reverse (s, s + strlen (s));
memset(a, 0, sizeof(a));
int L = strlen (s);
len = (L + 3) / 4;
int yu = L % 4 ? L % 4 : 4, cnt = len;
for (int i = 0; i < yu; i++)a[len] = a[len] * 10 + s[i] - '0';
for (int i = yu; s[i]; i += 4) {
int ret = 0;
for (int j = i; j <= i + 3; j++)ret = ret * 10 + s[j] - '0';
a[--cnt] = ret;
}
return ;
}
INT operator + (const INT b) {
INT c;
c.len = max(len, b.len);
for (int i = 1; i <= c.len; i++) {
c.a[i] += a[i] + b.a[i];
c.a[i + 1] = c.a[i] / TT;
c.a[i] %= TT;
}
if (c.a[c.len + 1])c.len++;
return c;
}
INT operator * (const INT b) {
INT c;
c.len = len + b.len - 1;
for (int i = 1; i <= len; i++)
for (int j = 1; j <= b.len; j++) {
c.a[i + j - 1] += a[i] * b.a[j];
c.a[i + j] += c.a[i + j - 1] / TT;
c.a[i + j - 1] %= TT;
}
if (c.a[c.len + 1]) c.len++;
while (c.len > 1 && !c.a[c.len]) c.len--;
return c;
}
void print () {
printf ("%d", a[len]);
for (int i = len - 1; i >= 1; i--) printf ("%04d", a[i]);
printf ("\n");
}
} vl[maxn], res;
# define int long long
INT change (int x) {
INT ret; ret.len = 0; memset (ret.a, 0, sizeof ret.a);
while (x) {
ret.a[++ret.len] = x % TT;
x /= TT;
}
return ret;
}
struct reader {
template <typename Type>
reader & operator >> (Type & ret) {
int f = 1; ret = 0; char ch = getchar ();
for (;!isdigit (ch); ch = getchar ()) if (ch == '-') f = -f;
for (; isdigit (ch); ch = getchar ()) ret = (ret * 10) + ch - '0';
ret *= f; return * this;
}
} fin;
int n, m, x, y, z, cnt[maxn];
int lnk[maxn], nxt[maxe], son[maxe], val[maxe], deg[maxn], tot;
void add_e (int x, int y, int z) {
nxt[++tot] = lnk[x]; lnk[x] = tot; son[tot] = y; val[tot] = z; deg[x]++;
nxt[++tot] = lnk[y]; lnk[y] = tot; son[tot] = x; val[tot] = z; deg[y]++;
return ;
}
int a[maxn]; bool vis[maxn];
queue < int > que;
void topo () {
while (!que.empty ()) que.pop ();
for (int i = 1; i <= n; i++) if (!--deg[i]) que.push (i);
while (!que.empty ()) {
int now = que.front (); que.pop (); vis[now] = true;
for (int j = lnk[now]; j; j = nxt[j]) {
if (!vis[son[j]]) cnt[val[j]] += abs (a[now]), a[son[j]] += a[now];
if (!--deg[son[j]]) que.push (son[j]);
}
}
return ;
}
wheneveright () {
fin >> n >> m;
for (int i = 1; i <= m; i++) fin >> x, a[x]++;
for (int i = 1; i <= m; i++) fin >> x, a[x]--;
for (int i = 1; i < n; i++) {
fin >> x >> y; vl[i].get ();
add_e (x, y, i);
}
topo ();
for (int i = 1; i < n; i++) res = res + (vl[i] * change (cnt[i]));
res.print ();
return 0;
}