Disillusioning #1 水题+原题赛(被虐瞎)
https://vijos.org/tests/542c04dc17f3ca2064fe7718
好一场 水题 比赛啊
t1直接上暴力费用流10分QAQ,虽然一开始我觉得可以不用的,直接dfs可以得出最大流,但是写撮了就放弃了。
t2直接上暴力又是10分QAQ,虽然本来我就不会。。
t3直接上暴力还写撮了。。。。。。。。sad story
orz 小岛 orz zyf
t1:P1885 Phorni(Disillusioning)
听zyf讲完后无限仰慕。。。。最大流的确可以dfs出来orzQAQ。然后费用流就麻烦了。。
因为是树型的,显然流量是全部流向叶子的,而且叶子到根有且只有一条路径!sigh。。。这样就能保证我选了一条费用最小的路径增广一定是最优!!贪心。。。
sad。
那么我用树剖+线段树维护路径最小,至于官方题解的lct实在是仰慕orz。虽然以前听说过lct优化的网络流,但是今天第一次遇到orz。有时间去看看。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << (#x) << " = " << (x) << endl #define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; } #define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl inline const int getint() { int r=0, k=1; char c= getchar (); for (; c< '0' ||c> '9' ; c= getchar ()) if (c== '-' ) k=-1; for (; c>= '0' &&c<= '9' ; c= getchar ()) r=r*10+c- '0' ; return k*r; } inline const int max( const int &a, const int &b) { return a>b?a:b; } inline const int min( const int &a, const int &b) { return a<b?a:b; } #define rdm(i, x) for(int i=ihead[x]; i; i=e[i].next) #define lc x<<1 #define rc x<<1|1 #define lson l, m, lc #define rson m+1, r, rc #define MID (l+r)>>1 const int N=100005, oo=~0u>>1; int n, ihead[N], cnt, d[N], id[N], fa[N], top[N], son[N], size[N], tot, num, cs[N], upd[N]; struct ED { int to, next, cap, cost; }e[N]; struct TR { int mn, tag; }t[N<<2]; struct ID { int c, id; }a[N]; void add( int u, int v, int c, int w) { e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].cap=c; e[cnt].cost=w; } void dfs( int x, int c, int t) { d[x]=0; int y; cs[x]=t; rdm(i, x) { y=e[i].to; dfs(y, e[i].cost+c, e[i].cap); d[x]+=min(d[y], e[i].cap); } if (!ihead[x]) d[x]=oo, a[++num].c=c, a[num].id=x; } void dfs1( int x) { size[x]=1; rdm(i, x) { int y=e[i].to; fa[y]=x; dfs1(y); if (size[y]>size[son[x]]) son[x]=y; size[x]+=size[y]; } } void dfs2( int x, int t) { id[x]=++tot; top[x]=t; upd[tot]=cs[x]; //dbg(x); dbg(tot); if (son[x]) dfs2(son[x], t); rdm(i, x) if (e[i].to!=son[x]) dfs2(e[i].to, e[i].to); } void pushup( int x) { t[x].mn=min(t[lc].mn, t[rc].mn); } void pushdown( int x) { if (t[x].tag) { int y=t[x].tag; t[x].tag=0; t[lc].mn+=y; t[rc].mn+=y; t[lc].tag+=y; t[rc].tag+=y; } } void build( int l, int r, int x) { t[x].mn=oo; if (l==r) { t[x].mn=upd[l]; return ; } int m=MID; build(lson); build(rson); pushup(x); } void update( int l, int r, int x, int L, int R, int k) { pushdown(x); if (L<=l && r<=R) { t[x].tag+=k; t[x].mn+=k; return ; } int m=MID; if (L<=m) update(lson, L, R, k); if (m<R) update(rson, L, R, k); pushup(x); } int query( int l, int r, int x, int L, int R) { pushdown(x); if (L<=l && r<=R) return t[x].mn; int m=MID, ret=oo; if (L<=m) ret=query(lson, L, R); if (m<R) ret=min(ret, query(rson, L, R)); return ret; } int getmin( int x) { int ret=oo; // dbg(x); while (top[x]!=1) { ret=min(ret, query(1, n, 1, id[top[x]], id[x])); x=fa[top[x]]; } ret=min(ret, query(1, n, 1, 1, id[x])); //dbg(ret); return ret; } void change( int x, int k) { while (top[x]!=1) { update(1, n, 1, id[top[x]], id[x], k); x=fa[top[x]]; } update(1, n, 1, 1, id[x], k); } bool cmp( const ID &a, const ID &b) { return a.c<b.c; } int main() { read(n); rep(i, n-1) { int u=getint(), v=getint(), c=getint(), w=getint(); add(u, v, c, w); } dfs(1, 0, oo); dfs1(1); dfs2(1, 1); build(1, n, 1); sort(a+1, a+1+num, cmp); int flow=d[1], ans=0; //for1(i, 1, cnt) for1(i, 1, num) { int f=min(flow, getmin(a[i].id)); // dbg(f); dbg(a[i].id); ans+=f*a[i].c; change(a[i].id, -f); flow-=f; if (flow==0) break ; } printf ( "%d\n%d\n" , d[1], ans); return 0; } |
无限仰膜zyf神犇,千古神犇zyf!
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix