BZOJ 2561 最小產生樹 【最大流】

來源:互聯網
上載者:User

標籤:

Description

 給定一個邊帶正權的連通無向圖G=(V,E),其中N=|V|,M=|E|,N個點從1到N依次編號,給定三個正整數u,v,和L (u≠v),假設現在加入一條邊權為L的邊(u,v),那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小產生樹上,也可能出現在最大產生樹上?

Solution

題意:在一個圖中,問一條邊即在最小產生樹上,又在最大產生樹上需要從圖上刪掉多少條邊

在最小產生樹上,一條邊不被選擇的充要條件是什麼呢?

當比它小的邊已經將它所串連的兩點串連起來的時候,這條邊就不能被選了

最大產生樹同樣

那麼,先只考慮最小產生樹的情況

如果這條邊不在最小產生樹中,邊權比它小的邊一定聯通了這條邊所接的節點u和v

我們想要花盡量少的代價使u,v不再聯通

顯然問題轉化為了最小割

對最小產生樹做一次再對最大產生樹做一次,答案加起來就可以了

  1 #include<bits/stdc++.h>  2   3 #define maxn 20000+5  4 #define maxm 600000+5  5 #define set(a,b) memset(a,(b),sizeof(a))  6 #define fr(i,a,b) for(ll i=(a),_end_=(b);i<=_end_;i++)  7 #define rf(i,b,a) for(ll i=(a),_end_=(b);i>=_end_;i--)  8 #define fe(i,a,b) for(int i=first[(b)],_end_=(a);i!=_end_;i=s[i].next)  9 #define fec(i,a,b) for(int &i=cur[(b)],_end_=(a);i!=_end_;i=s[i].next) 10  11 using namespace std; 12  13 typedef long long ll; 14  15 struct sides{ 16   int u,v,c; 17   int next; 18 }s[maxm]; 19  20 struct edge{ 21   int u,v,w; 22   friend bool operator < (edge a,edge b){ 23     return a.w<b.w; 24   } 25 }e[maxm]; 26  27 queue<int> q; 28 int h[maxn],first[maxn],cur[maxn]; 29 int ind=0; 30 int cost=0; 31 int n,m,sp,tp,p; 32  33 bool comp(edge a,edge b) 34 { 35   return a.w<b.w; 36 } 37  38 void add(int u,int v,int c) 39 { 40   s[ind].u=u,s[ind].v=v,s[ind].c=c; 41   s[ind].next=first[u],first[u]=ind; 42   ind++; 43    44   s[ind].u=v,s[ind].v=u,s[ind].c=c; 45   s[ind].next=first[v],first[v]=ind; 46   ind++; 47 } 48  49 bool bfs() 50 { 51   set(h,-1); 52   h[sp]=0; 53   q.push(sp); 54   while( !q.empty() ){ 55     int sd=q.front();q.pop(); 56     fe(i,-1,sd) 57       if( h[s[i].v]==-1 && s[i].c ){ 58     h[s[i].v]=h[sd]+1; 59     q.push(s[i].v); 60       } 61   } 62   return h[tp]!=-1; 63 } 64  65 int dfs(int sd,int flow) 66 { 67   if( sd==tp ) return flow; 68   int w,used=0; 69   fec(i,-1,sd) 70     if( h[s[i].v]==h[sd]+1 && s[i].c ){ 71       w=dfs(s[i].v,min(flow-used,s[i].c)); 72       s[i].c-=w,s[i^1].c+=w; 73       used+=w; 74       if( used==flow ) return flow; 75     } 76   if( !used ) h[sd]=1; 77   return used; 78 } 79  80 void dinic() 81 { 82   while( bfs() ){ 83     fr(i,0,n+1) 84       cur[i]=first[i]; 85     cost+=dfs(sp,INT_MAX); 86   } 87 } 88  89 void solve() 90 { 91   ind=0; 92   set(first,-1); 93   fr(i,1,m) 94     if( e[i].w<p ) 95       add(e[i].u,e[i].v,1); 96     else break; 97   dinic(); 98    99   ind=0;100   set(first,-1);101   rf(i,1,m)102     if( e[i].w>p )103       add(e[i].u,e[i].v,1);104     else break;105   dinic();106 }107 108 int main()109 {110 #ifndef ONLINE_JUDGE111   freopen("2561.in","r",stdin);112   freopen("2561.out","w",stdout);113 #endif114   cin >> n >> m ;115   fr(i,1,m)116     cin >> e[i].u >> e[i].v >> e[i].w ;117   sort(e+1,e+m+1,comp);118   cin >> sp >> tp >> p ;119   solve();120   cout << cost ;121   return 0;122 }

 

BZOJ 2561 最小產生樹 【最大流】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.