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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【模板】最大密度子图

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【模板】最大密度子图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ACM模板


目錄

      • 概念
      • 做法
      • 例題

概念

選擇一個子圖G′=(V′,E′)G'=(V',E')G=(V,E),其中對于任意一條邊的兩個端點必須在所選的點集中,最大化∣E′∣∣V′∣\frac{|E'|}{|V'|}VE?

做法

利用01分數規劃二分即最大化
∣E′∣?g∣V′∣|E'|-g|V'|E?gV
也就是最小化g∣V′∣?∣E′∣=∑v∈V′g?∑v∈V′1=∑v∈V′g?12(∑v∈V′dv?c[V′,V′ˉ])=12(∑v∈V′(2g?dv)+c[V′,V′ˉ])g|V'|-|E'|=\sum_{v\in V'}g-\sum_{v\in V'}1=\sum_{v\in V'}g-\frac{1}{2}(\sum_{v\in V'}d_v-c[V',\bar{V'}])=\frac 1 2(\sum_{v\in V'}(2g-d_v)+c[V',\bar{V'}])gV?E=vV?g?vV?1=vV?g?21?(vV?dv??c[V,Vˉ])=21?(vV?(2g?dv?)+c[V,Vˉ])
我們發現除了割邊還有一個東西即∑v∈V′(2g?dv)\sum_{v\in V'}(2g-d_v)vV?(2g?dv?),只需要將每個點連向匯點一條容量是2g?dv2g-d_v2g?dv?的邊即可讓構建的割的容量是上述式子。因為對于V′V'V中的點要求與源點SSS放在一起,那么只要它與匯點存在邊就會對割的容量由貢獻。

建圖:原圖中的點與邊的容量都是1,再加上所有點向匯點連邊容量是2g?dv2g-d_v2g?dv?
那么構建出的網絡流的割的容量c[S,T]=2(g∣V′∣?∣E′∣)c[S,T]=2(g|V'|-|E'|)c[S,T]=2(gV?E)
于是g∣V′∣?∣E′∣=12c[S,T]g|V'|-|E'|=\frac{1}{2}c[S,T]gV?E=21?c[S,T]
即求最小割。

為了防止連向匯點的邊權2g?dv2g-d_v2g?dv?是負值,需要增添一個偏移量UUU
重新建圖即:①源點向每個點連邊,容量是UUU;②原圖中的邊,容量是1;③每個點向匯點連邊,容量是2g?dv+U2g-d_v+U2g?dv?+U
可證g∣V′∣?∣E′∣=12(c[S,T]?nU)g|V'|-|E'|=\frac{1}{2}(c[S,T]-nU)gV?E=21?(c[S,T]?nU)

最初需要最大化的值即∣E′∣?g∣V′∣=nU?c[S,T]2|E'|-g|V'|=\frac{nU-c[S,T]}{2}E?gV=2nU?c[S,T]?

不難看出如果我們這里把邊看成點,選邊必須選擇兩個端點的限制可以加到邊上即邊向兩個端點連單向邊即可以轉化為最大權閉合圖問題

類型建圖點數建圖邊數
最大密度子圖|V|2|V|+|E|
最大權閉合圖|V|+|E||V|+3|E|

如果存在邊權密度:∑e∈EWe∣V∣\frac{\sum_{e\in E} W_e}{|V|}VeE?We??
dvd_vdv?記為該點出邊權值和而不是出度即可

若存在點權和邊權密度∑v∈Vpv+∑e∈EWe∣V∣\frac{\sum_{v\in V}p_v+\sum_{e\in E} W_e}{|V|}VvV?pv?+eE?We??
dvd_vdv?記為該點出邊權值和
②連向匯點和源點的邊容量是2g?dv?2pv+U2g-d_v-2p_v+U2g?dv??2pv?+U

例題

#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N=5010,M=(50000+2*N)*2+10,INF=0x3f3f3f3f; int n,m; int h[N],e[M],ne[M],f[M],idx; int S,T,d[N],q[N],cur[N]; int deg[N],p[N]; void add(int a,int b,int c1,int c2) {e[idx]=b,ne[idx]=h[a],f[idx]=c1,h[a]=idx++;e[idx]=a,ne[idx]=h[b],f[idx]=c2,h[b]=idx++; } bool bfs() {memset(d,-1,sizeof d);int tt=0,hh=0;q[S]=0,cur[S]=h[S],d[S]=0;while(hh<=tt){int t=q[hh++];for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]==-1&&f[i]){d[j]=d[t]+1;cur[j]=h[j];if(j==T) return 1;q[++tt]=j;}}}return 0; } int dfs(int u=S,int flow=INF) {if(u==T) return flow;int rmn=flow;for(int i=cur[u];i!=-1&&rmn;i=ne[i]){cur[u]=i;int j=e[i];if(d[j]==d[u]+1&&f[i]){int t=dfs(j,min(f[i],rmn));if(!t) d[j]=-1;f[i]-=t,f[i^1]+=t,rmn-=t;}}return flow-rmn; } int dinic() {int r=0;while(bfs()) r+=dfs();return r; } int main() {cin>>n>>m;memset(h,-1,sizeof h);S=0,T=n+1;for(int i=1;i<=n;i++) cin>>p[i],p[i]*=-1;while(m--){int a,b,c;cin>>a>>b>>c;add(a,b,c,c);deg[a]+=c,deg[b]+=c;//記錄出邊權值和}int U=0;for(int i=1;i<=n;i++) U=max(U,2*p[i]+deg[i]);for(int i=1;i<=n;i++) add(S,i,U,0),add(i,T,U-2*p[i]-deg[i],0);cout<<(U*n-dinic())/2<<'\n';return 0; }

總結

以上是生活随笔為你收集整理的【模板】最大密度子图的全部內容,希望文章能夠幫你解決所遇到的問題。

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