HDU 3526 Computer Assembling(最小割)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3526 Computer Assembling(最小割)相关的知识,希望对你有一定的参考价值。

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

题意:
有个屌丝要配置电脑,现在有n个配件需要购买,有两家公司出售这n个配件,还有m个条件是如果配件x和配件y在不同公司买的话,需要花费额外的w元。现在需要计算购买这n个配件的最小花费。

 

思路:

一开始想的费用流,但好像不太行??

其实一看到二选一的话就首先应该往最小割和二分图这个方向去想一想的。

这题用最小割来做,对于这m条件,在这两个顶点之间加两条有向边。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<queue>
  7 using namespace std;
  8 const int INF = 0x3f3f3f3f;
  9 const int maxn = 500+5;
 10 
 11 int n,m;
 12 
 13 struct Edge
 14 {
 15     int from,to,cap,flow;
 16     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 17 };
 18 
 19 struct Dinic
 20 {
 21     int n,m,s,t;
 22     vector<Edge> edges;
 23     vector<int> G[maxn];
 24     bool vis[maxn];
 25     int cur[maxn];
 26     int d[maxn];
 27 
 28     void init(int n)
 29     {
 30         this->n=n;
 31         for(int i=0;i<n;++i) G[i].clear();
 32         edges.clear();
 33     }
 34 
 35     void AddEdge(int from,int to,int cap)
 36     {
 37         edges.push_back( Edge(from,to,cap,0) );
 38         edges.push_back( Edge(to,from,0,0) );
 39         m=edges.size();
 40         G[from].push_back(m-2);
 41         G[to].push_back(m-1);
 42     }
 43 
 44     bool BFS()
 45     {
 46         queue<int> Q;
 47         memset(vis,0,sizeof(vis));
 48         vis[s]=true;
 49         d[s]=0;
 50         Q.push(s);
 51         while(!Q.empty())
 52         {
 53             int x=Q.front(); Q.pop();
 54             for(int i=0;i<G[x].size();++i)
 55             {
 56                 Edge& e=edges[G[x][i]];
 57                 if(!vis[e.to] && e.cap>e.flow)
 58                 {
 59                     vis[e.to]=true;
 60                     d[e.to]=d[x]+1;
 61                     Q.push(e.to);
 62                 }
 63             }
 64         }
 65         return vis[t];
 66     }
 67 
 68     int DFS(int x,int a)
 69     {
 70         if(x==t || a==0) return a;
 71         int flow=0, f;
 72         for(int &i=cur[x];i<G[x].size();++i)
 73         {
 74             Edge &e=edges[G[x][i]];
 75             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 76             {
 77                 e.flow +=f;
 78                 edges[G[x][i]^1].flow -=f;
 79                 flow +=f;
 80                 a -=f;
 81                 if(a==0) break;
 82             }
 83         }
 84         return flow;
 85     }
 86 
 87     int Maxflow(int s,int t)
 88     {
 89         this->s=s; this->t=t;
 90         int flow=0;
 91         while(BFS())
 92         {
 93             memset(cur,0,sizeof(cur));
 94             flow +=DFS(s,INF);
 95         }
 96         return flow;
 97     }
 98 }DC;
 99 
100 int main()
101 {
102     //freopen("in.txt","r",stdin);
103     while(~scanf("%d%d",&n,&m))
104     {
105         int src = 0, dst = n+1;
106         DC.init(dst+1);
107         for(int i=1;i<=n;i++)
108         {
109             int x;scanf("%d",&x);
110             DC.AddEdge(src,i,x);
111         }
112         for(int i=1;i<=n;i++)
113         {
114             int x;scanf("%d",&x);
115             DC.AddEdge(i,dst,x);
116         }
117         while(m--)
118         {
119             int u,v,w;
120             scanf("%d%d%d",&u,&v,&w);
121             DC.AddEdge(u,v,w);
122             DC.AddEdge(v,u,w);
123         }
124         printf("%d\n",DC.Maxflow(src,dst));
125     }
126     return 0;
127 }

 

以上是关于HDU 3526 Computer Assembling(最小割)的主要内容,如果未能解决你的问题,请参考以下文章

Hdu2196 Computer

HDU 2169 Computer[树形dp]

HDU - 2196 Computer

Computer HDU - 2196

hdu2196Computer

hdu 2196 Computer 树的直径