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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 3947 River Problem

發(fā)布時(shí)間:2024/10/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 3947 River Problem 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://acm.hdu.edu.cn/showproblem.php?pid=3947

題意:一個(gè)有向樹(河流),只有一個(gè)匯點(diǎn)1,每條邊只有一個(gè)出度。有些河道有污染指數(shù)xi,必需要治理,有m段路徑,可以去覆蓋這些,每被覆蓋一次,xi降低響應(yīng)值。

即 給出一些邊必需要覆蓋的次數(shù),用m段路徑去覆蓋,每次覆蓋有相應(yīng)費(fèi)用,求最小費(fèi)用。

題解:網(wǎng)絡(luò)流+最小費(fèi)用流+流量不等式建圖

先設(shè)立超級源匯S=0、T=1。

首先對給定的樹邊建立反向邊,然后從結(jié)點(diǎn)1開始遍歷整棵樹,如果到達(dá)葉子結(jié)點(diǎn)x,則建邊(S,x,M,0)(其中M為大整數(shù))。

如果v不是葉子結(jié)點(diǎn),且v的父節(jié)點(diǎn)為u,(u,v)的邊權(quán)為w,則看x的子樹內(nèi)葉子結(jié)點(diǎn)的個(gè)數(shù)num,建邊(v,u,num*M-w,0)。

最后對所有的道具建邊(u,v,c,w)。

最后跑一遍最小費(fèi)用最大流,如果流量等于以1為根結(jié)點(diǎn)的數(shù)的葉子節(jié)點(diǎn)個(gè)數(shù)*M,則輸出cost,否則輸出-1。

可認(rèn)為道具是彌補(bǔ)流量不足的情況的。

流量不等式建圖

道具加邊

?

/* *@Author: STZG *@Language: C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int #define endl "\n" using namespace std; typedef long long ll; //typedef __int128 lll; const int N=1000+10; const int M=10000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const int INF = 0x3f3f3f3f; int s,t,n,m,k,p,l,r,u,v,w,c; ll ans,flag,temp,sum,minz,maxflow; ll dis[N]; bool vis[N]; struct Node{int u,v;ll w;Node(){};Node(int form,int to,ll w):u(form),v(to),w(w){} }; struct node{int u,v;ll c,w;node(){};node(int form,int to,ll cap,ll w):u(form),v(to),c(cap),w(w){} }; vector<node>edge; vector<int> G[N]; vector<Node>Edge[N]; void Addedge(int u,int v,ll cap,ll w){edge.push_back({u,v,cap,w});edge.push_back({v,u,0,-w});//cout<<u<<" "<<v<<" "<<cap<<endl;int sz=edge.size();G[u].push_back(sz-2);G[v].push_back(sz-1); } bool bfs(int u){//memset(dis,-1,sizeof(dis));for(int i=0;i<=n;i++)dis[i]=INF,vis[i]=0;dis[u]=0;queue<int>q;q.push(u);vis[u]=1;while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=0;i<G[u].size();i++){node e=edge[G[u][i]];//cout<<u<<" bfs "<<e.v<<endl;if(dis[e.v]>dis[u]+e.w&&e.c>0){dis[e.v]=dis[u]+e.w;if(!vis[e.v]){vis[e.v]=1;q.push(e.v);}}}}return dis[t]!=INF; } int dfs(int u,ll flow){vis[u]=1;if(u==t)return flow;int now;for(int i=0;i<G[u].size();i++){node e=edge[G[u][i]];//cout<<u<<" dfs "<<e.v<<endl;if((!vis[e.v]||e.v==t)&&e.c>0&&dis[u]+e.w==dis[e.v]&&(now=dfs(e.v,min(flow,e.c)))){ans+=e.w*now;//cout<<now<<endl;edge[G[u][i]].c-=now;edge[G[u][i]^1].c+=now;return now;}}return 0; } void dinic(){while(bfs(s)){//cout<<ans<<endl;int res=0;while((res=dfs(s,INF))){maxflow+=res;memset(vis,0,sizeof(vis));}} } int DFS_TREE(int u){if(Edge[u].size()==0){Addedge(s,u,M,0);return 1;}int res=0;for(int i=0;i<Edge[u].size();i++){int v=Edge[u][i].v;//cout<<u<<" tree "<<v<<endl;int leaf=DFS_TREE(v);res+=leaf;Addedge(v,u,leaf*M-Edge[u][i].w,0);}return res; } void init(){s=0;t=1;for(int i=0;i<=n;i++)G[i].clear(),Edge[i].clear();edge.clear();ans=0;sum=0;maxflow=0; } int main() { #ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout); #endif//ios::sync_with_stdio(false);//cin.tie(0);//cout.tie(0);scanf("%d",&k);int T=0;while(k--){scanf("%d",&n);init();for(int i=1;i<n;i++){scanf("%d%d%d",&u,&v,&c);Edge[v].push_back({v,u,c});}sum=DFS_TREE(1)*M;scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%d%d%d%d",&u,&v,&c,&w);Addedge(u,v,c,w);}dinic();//cout<<maxflow<<endl;cout<<"Case #"<<++T<<": "<<(maxflow==sum?ans:-1)<<endl;}#ifdef DEBUGprintf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC); #endif//cout << "Hello world!" << endl;return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的HDU 3947 River Problem的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。