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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

無向圖聯通分量

點u是割點,當且僅當

  • 特判樹根:u為樹根,且u有多于1棵子樹
  • u不為樹根,在遞歸樹上u存在子節點v,滿足:dfnu≤lowv\text{dfn}_u\leq \text{low}_vdfnu?lowv?


如上圖,v想走到u的組先必須經過u,那么u一定是割點。


(u,v)(u,v)(u,v)是割邊,當且僅當邊(u,v)(u,v)(u,v)為樹邊,且滿足dfnu<lowv?dfnv=lowv\text{dfn}_u< \text{low}_v\Leftrightarrow \text{dfn}_v= \text{low}_vdfnu?<lowv??dfnv?=lowv?

  • 從v出發無法到達u以及u的祖先
  • 非樹邊不可能是割邊,重邊不可能是割邊

J-Defend Your Country

Zechariah_2001題解
Alkaid~題解

下面結論詳細證明可以參考上面兩位大佬的題解

結論

  • 對于nnn是偶數的情況,顯然不需要刪邊。

  • 對于nnn是奇數的情況,最優方案一定是只刪除一個點連接的所有邊,只有這個點的貢獻會變負。刪去非割點顯然只用刪一個,刪掉割點必須保證刪除后連通塊點數都是偶數。

Code

#include<bits/stdc++.h> using namespace std; using ll=long long; template <class T=int> T rd() {T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg; } const int N=1000010; int h[N],e[N<<2],ne[N<<2],idx; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} int n,m,a[N]; ll sum; int dfn[N],low[N],sz[N],timestamp; bool cut[N],no[N]; void tarjan(int u,int fa) {dfn[u]=low[u]=++timestamp;sz[u]=1;int chd=0;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(!dfn[v]){tarjan(v,u);sz[u]+=sz[v];low[u]=min(low[u],low[v]);if(low[v]>=dfn[u]) {if(fa) cut[u]=1;// 根節點特判,v最多走到u走不到u上面去if(sz[v]&1) no[u]=1;}if(!fa) ++chd;// 特判根節點}else if(v!=fa) low[u]=min(low[u],dfn[v]);}if(chd>1) cut[u]=1; } void init() {idx=0;sum=0;timestamp=0;for(int i=1;i<=n;i++) h[i]=-1;for(int i=1;i<=n;i++) dfn[i]=low[i]=sz[i]=0;for(int i=1;i<=n;i++) no[i]=cut[i]=0; } int main() {int Tc=rd();while(Tc--){n=rd(),m=rd();init();for(int i=1;i<=n;i++) a[i]=rd(),sum+=a[i];while(m--){int u=rd(),v=rd();add(u,v),add(v,u);}if(n&1) {tarjan(1,0);int mn=0x3f3f3f3f;for(int i=1;i<=n;i++)if(!cut[i]||!no[i]) mn=min(mn,a[i]);printf("%lld\n",sum-2*mn);}else printf("%lld\n",sum);} }

總結

以上是生活随笔為你收集整理的2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)的全部內容,希望文章能夠幫你解決所遇到的問題。

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