【HDOJ】4729 An Easy Problem for Elfness
2016-02-15 15:04
295 查看
其实是求树上的路径间的数据第K大的题目。
果断主席树 + LCA。
初始流量是这条路径上的最小值。
若a<=b,显然直接为s->t建立pipe可以使流量最优;
否则,对【0, 10**4】二分得到boundry,使得boundry * n_edge - sum_edge <= k/b, 或者建立s->t,然后不断extend s->t。
数据发生器。
果断主席树 + LCA。
初始流量是这条路径上的最小值。
若a<=b,显然直接为s->t建立pipe可以使流量最优;
否则,对【0, 10**4】二分得到boundry,使得boundry * n_edge - sum_edge <= k/b, 或者建立s->t,然后不断extend s->t。
/* 4729 */ #include <iostream> #include <sstream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) // #define lson l, mid, rt<<1 // #define rson mid+1, r, rt<<1|1 typedef struct { int v, c, nxt; } edge_t; const int maxn = 1e5+5; const int m = 10005; const int maxm = maxn * 20; int T[maxn]; int lson[maxm], rson[maxm], c[maxm], sum[maxm]; int head[maxn], l; edge_t E[maxn<<1]; int tot, n, q; int beg[maxn]; int V[maxn<<1], D[maxn<<1], top; int dp[18][maxn<<1]; void init() { memset(head, -1, sizeof(head)); l = top = 0; tot = 1; } int Build(int l, int r) { int rt = tot++; c[rt] = sum[rt] = 0; if (l == r) return rt; int mid = (l + r) >> 1; lson[rt] = Build(l, mid); rson[rt] = Build(mid+1, r); return rt; } int Insert(int rt, int x, int val) { int nrt = tot++, ret = nrt; int l = 0, r = m - 1, mid; c[nrt] = c[rt] + 1; sum[nrt] = sum[rt] + val; while (l < r) { mid = (l + r) >> 1; if (x <= mid) { lson[nrt] = tot++; rson[nrt] = rson[rt]; nrt = lson[nrt]; rt = lson[rt]; r = mid; } else { lson[nrt] = lson[rt]; rson[nrt] = tot++; nrt = rson[nrt]; rt = rson[rt]; l = mid + 1; } c[nrt] = c[rt] + 1; sum[nrt] = sum[rt] + val; } return ret; } int Query_kth(int urt, int vrt, int frt, int k) { int l = 0, r = m - 1, mid; int tmp; while (l < r) { mid = (l + r) >> 1; tmp = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << 1); if (tmp >= k) { urt = lson[urt]; vrt = lson[vrt]; frt = lson[frt]; r = mid; } else { k -= tmp; urt = rson[urt]; vrt = rson[vrt]; frt = rson[frt]; l = mid + 1; } } return l; } int Query_Bound(int urt, int vrt, int frt, int delta) { int l = 0, r = m - 1, mid; int cc = 0, csum = 0; int tc, tsum; int ans = 0, tmp; while (l < r) { mid = (l + r) >> 1; tc = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << 1); tsum = sum[lson[urt]] + sum[lson[vrt]] - (sum[lson[frt]] << 1); tmp = mid*(tc+cc)-(tsum+csum); if (tmp <= delta) ans = max(ans, mid); if (mid*(tc+cc)-(tsum+csum) >= delta) { urt = lson[urt]; vrt = lson[vrt]; frt = lson[frt]; r = mid; } else { urt = rson[urt]; vrt = rson[vrt]; frt = rson[frt]; cc += tc; csum += tsum; l = mid + 1; } } return ans; } void addEdge(int u, int v, int c) { E[l].v = v; E[l].c = c; E[l].nxt = head[u]; head[u] = l++; E[l].v = u; E[l].c = c; E[l].nxt = head[v]; head[v] = l++; } void dfs(int u, int fa, int dep) { int v, k; V[++top] = u; D[top] = dep; beg[u] = top; for (k=head[u]; k!=-1; k=E[k].nxt) { v = E[k].v; if (v == fa) continue; T[v] = Insert(T[u], E[k].c, E[k].c); dfs(v, u, dep+1); V[++top] = u; D[top] = dep; } } void Init_RMQ(int n) { int i, j; for (i=1; i<=n; ++i) dp[0][i] = i; for (j=1; (1<<j)<=n; ++j) for (i=1; i+(1<<j)-1<=n; ++i) if (D[dp[j-1][i]] < D[dp[j-1][i+(1<<(j-1))]]) dp[j][i] = dp[j-1][i]; else dp[j][i] = dp[j-1][i+(1<<(j-1))]; } int RMQ(int l, int r) { if (l > r) swap(l, r); int k = 0; while (1<<(k+1) <= r-l+1) ++k; if (D[dp[k][l]] < D[dp[k][r-(1<<k)+1]]) return V[dp[k][l]]; else return V[dp[k][r-(1<<k)+1]]; } void solve() { T[1] = Build(0, m - 1); dfs(1, 0, 0); Init_RMQ(top); int u, v, k, a, b; int lca; int ans, tmp, org; while (q--) { scanf("%d %d %d %d %d", &u, &v, &k, &a, &b); lca = RMQ(beg[u], beg[v]); org = Query_kth(T[u], T[v], T[lca], 1); #ifndef ONLINE_JUDGE // printf("f = %d\n", lca); #endif if (a <= b) { ans = org + k / a; } else { ans = org; if (k >= a) ans += 1 + (k-a)/b; tmp = Query_Bound(T[u], T[v], T[lca], k/b); #ifndef ONLINE_JUDGE // printf("org = %d, ans = %d, bound = %d\n", org, ans, tmp); #endif ans = max(ans, tmp); } printf("%d\n", ans); } } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif int t; int u, v, c; scanf("%d", &t); rep(tt, 1, t+1) { init(); scanf("%d %d", &n, &q); rep(i, 1, n) { scanf("%d %d %d", &u, &v, &c); addEdge(u, v, c); } printf("Case #%d:\n", tt); solve(); } #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
数据发生器。
from copy import deepcopy from random import randint, shuffle import shutil import string def GenDataIn(): with open("data.in", "w") as fout: t = 10 bound = 10**4 fout.write("%d\n" % (t)) for tt in xrange(t): n = randint(100, 200) q = randint(100, 200) fout.write("%d %d\n" % (n, q)) ust = [1] vst = range(2, n+1) for i in xrange(1, n): idx = randint(0, len(ust)-1) u = ust[idx] idx = randint(0, len(vst)-1) v = vst[idx] ust.append(v) vst.remove(v) c = randint(0, bound-1) fout.write("%d %d %d\n" % (u, v, c)) for i in xrange(q): u = randint(1, n) while True: v = randint(1, n) if v!=u: break k = randint(0, bound) a = randint(1, bound) b = randint(1, bound) fout.write("%d %d %d %d %d\n" % (u, v, k, a, b)) def MovDataIn(): desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" shutil.copyfile("data.in", desFileName) if __name__ == "__main__": GenDataIn() MovDataIn()
相关文章推荐
- ssh 免密码登录
- TinyOS视频第三集内容介绍
- toolbar遇到问题和解决方式
- faad2解码aac-解决采样频率和通道数不对的问题
- MVP使用
- 绘图(VC_Win32)
- gradle批量打包apk
- adroid 基础 imgeButton
- DOM Insertion, Inside 追加元素内容
- HTML5 data-* 自定义属性
- codevs 3286 火柴排队
- 在Mac OS的PHP环境下安装配置MemCache的全过程解析
- [Python]网络爬虫2
- git push error: failed to push some refs to 'ssh://git@ip:8850/Out/Afuyigou.
- 关闭Tomcat日志输出catalina.out
- Java中String类的isEmpty方法、null以及""的区别
- 如何从京东商品里获取需要的信息
- UIImagePickerController详解
- gz文件的解压和压缩
- Qt窗口句柄