日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P3128 [USACO15DEC]最大流Max Flow

發布時間:2024/9/5 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3128 [USACO15DEC]最大流Max Flow 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P3128 [USACO15DEC]最大流Max Flow

對,這是一道最大流的題目qwq

樹上跑最大流,沒錯

也就是跑最小割

你看名字里都有最大流,為什么不能跑最大流qwq..............................
編不下去了

跑樹上差分。

就像數組上可以進行差分一樣,樹上也可以進行差分。適用于樹上兩點之間的路徑操作,和極少數的查詢

適用于維護路徑長可以進行結合律的操作

比如說我們要在樹上進行兩點之間的路徑上的節點值加一個數,最后輸出所有節點值之和。

我們可以進行樹鏈剖分,可是使用樹鏈剖分有些大材小用了,而且常數巨大

我們就可以使用差分

比如說這么一棵樹

我們要使得8到11的路徑上的點加3

我們就可以設一個數組,\(t[i]\)表示這棵樹的差分數組,\(st[i][j]\)表示樹上的倍增數組

然后我們令\(t[8]+=3,t[11]+=3,t[lca_{(8,11)}]-=3,t[st[lca_{(8,11)}][0]]-=3\)

然后我們將差分數組使用以下程序進行整理整理,然后進行查詢。

void DFS(int now,int fa) {int pas=0;for(int i=head[now];i;i=line[i].nxt)if(line[i].p!=fa){DFS(line[i].p,now);t[now]+=t[line[i].p];} }

將所有點上的值遞歸加起來,就成了下圖的情況。成功實現了O(1)修改,O(N)查詢


而對于維護邊權呢?我們可以將邊權下放至所連點中深度最深的點上去

然后將差分時的\(t[st[lca_{(a,b)}][0]]-=add,t[lca_{(a,b)}]-=add\)變為\(t[lca_{(a,b)}]-add*2\)就可以了,樹鏈剖分也可以將邊權下放至點

此題\(code\)

#include<cstdio> #include<algorithm> #include<iostream> using std::swap; using std::max; const int maxn=50100; struct node {int p;int nxt; }; node line[maxn<<1]; int head[maxn],tail; void add(int a,int b) {line[++tail].p=b;line[tail].nxt=head[a];head[a]=tail; } int st[maxn][20]; int log[maxn]; int dep[maxn]; int ans,t[maxn]; void dfs(int now,int fa) {st[now][0]=fa;dep[now]=dep[fa]+1;for(int i=1;i<=log[dep[now]];i++)st[now][i]=st[st[now][i-1]][i-1];for(int i=head[now];i;i=line[i].nxt)if(line[i].p!=fa)dfs(line[i].p,now); } int lca(int a,int b) {if(dep[a]<dep[b]) swap(a,b);for(int i=log[dep[a]];i>=0;i--)if(dep[st[a][i]]>=dep[b])a=st[a][i];if(a==b) return a;for(int i=log[dep[a]];i>=0;i--)if(st[a][i]!=st[b][i])a=st[a][i],b=st[b][i];return st[a][0]; } void DFS(int now,int fa) {int pas=0;for(int i=head[now];i;i=line[i].nxt)if(line[i].p!=fa){DFS(line[i].p,now);t[now]+=t[line[i].p];}ans=max(ans,t[now]); } int main() {int n,k;scanf("%d%d",&n,&k);for(int i=2;i<=n;i++) log[i]=log[i>>1]+1;int a,b;for(int i=1;i<n;i++){scanf("%d%d",&a,&b);add(a,b);add(b,a);}dfs(1,0);for(int i=1;i<=k;i++){scanf("%d%d",&a,&b);t[a]++;t[b]++;int LCA=lca(a,b);t[LCA]--; t[st[LCA][0]]--;}DFS(1,0);printf("%d",ans); }

轉載于:https://www.cnblogs.com/Lance1ot/p/9403259.html

總結

以上是生活随笔為你收集整理的P3128 [USACO15DEC]最大流Max Flow的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。