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 }

 

posted @ 2017-12-05 19:28  Kayden_Cheung  阅读(219)  评论(0编辑  收藏  举报
//目录