HDU ACM 4494 Teamwork 最小费用最大流
来源:互联网 发布:js判断滚动条位置 编辑:程序博客网 时间:2024/05/22 12:25
题意:n个工作地,m种工人,工作地0是仓库,其他的都需要修缮,每个地点需要多个工种的工人若干,不同工种不能相互取代。每个工作地有一个开工时间,凑齐所有工人后准时开工,修缮也需要一定时间。一个工人可以在一个地方工作完后再到其他地方,两地直接的距离是欧几里得距离,可以算作时间。最少需要多少工人。
分析:只用费用流。每种工人不能相互替换,没有任何关系。因此对每个工种进行建图求解最小费用累加即可得到最终结果。
超级源点cs是仓库,超级汇点为ct。
一个地点拆成三个点,i、i’、i”。k表示工种,对每个点建边。
S -> i : 容量为v[i][k],费用为1.
i -> i’ : 容量为v[i][k],费用为0.
i’ -> T : 容量为v[i][k],费用为0.S -> i” : 容量为v[i][k],费用为0.
如果工人可以在地点i工作完成后到达地点j开工,建边i” -> j’ : 容量为v[i][k],费用为0.这样建边相当于j点的流量减小了v[i][k]。
#include<iostream>#include<vector>#include<queue>#include<cmath>using namespace std; #define N 500#define inf 0x3f3f3f3f#define min(a,b) ((a)<(b)?(a):(b))class MCMF //最小费用最大流{ private: struct EDGE { EDGE(int _from,int _to,int _cap,int _flow,int _cost) { from=_from; to=_to; cap=_cap; flow=_flow; cost=_cost; } int from,to,cap,flow,cost; }; public: MCMF(){ m_iM=0;} ~MCMF(){} void AddEdge(int _from,int _to,int _cap,int _cost); //_cap表示容量 int MinCost(int s,int t);void Init(int n); private:bool BellmanFord(int s,int t,int& flow,int& cost); //沿最短路增广 int m_iN,m_iM,m_iS,m_iT; //节点数,边数(包括反向边),源点,汇点 vector<EDGE> m_vEdges; //边表m_edges[e]和m_edges[e^1]互为反向弧 vector<int> m_vG[N]; //领接表 int m_iD[N]; //Bellman-Fordint m_iP[N]; //上一条弧int m_iA[N]; //可改进量bool m_bInq[N]; //是否在队列中};int MCMF::MinCost(int s,int t){int flow=0,cost=0;while(BellmanFord(s,t,flow,cost)) ; //求出最小费用最大流return cost;}void MCMF::Init(int n){int i;for(i=0;i<n;i++) m_vG[i].clear();m_vEdges.clear();m_iM=0;m_iN=n;}void MCMF::AddEdge(int _from,int _to,int _cap,int _cost) { m_vEdges.push_back(EDGE(_from,_to,_cap,0,_cost)); m_vEdges.push_back(EDGE(_to,_from,0,0,-_cost)); m_iM+=2; m_vG[_from].push_back(m_iM-2); m_vG[_to].push_back(m_iM-1); }bool MCMF::BellmanFord(int s,int t,int& flow,int& cost){int i,u;for(i=0;i<m_iN;i++) m_iD[i]=inf;memset(m_bInq,false,sizeof(m_bInq));m_iD[s]=0;m_bInq[s]=1;m_iP[s]=0;m_iA[s]=inf;queue<int> q;q.push(s);while(!q.empty()){u=q.front();q.pop();m_bInq[u]=false;for(i=0;i<m_vG[u].size();i++){EDGE& e=m_vEdges[m_vG[u][i]];if(e.cap>e.flow && m_iD[e.to]>m_iD[u]+e.cost){m_iD[e.to]=m_iD[u]+e.cost;m_iP[e.to]=m_vG[u][i];m_iA[e.to]=min(m_iA[u],e.cap-e.flow);if(!m_bInq[e.to]){q.push(e.to);m_bInq[e.to]=true;}}}}if(m_iD[t]==inf) return false; //s-t不连通,找不到增广路flow+=m_iA[t];cost+=m_iD[t]*m_iA[t];u=t;while(u!=s){m_vEdges[m_iP[u]].flow+=m_iA[t];m_vEdges[m_iP[u]^1].flow-=m_iA[t];u=m_vEdges[m_iP[u]].from;}return true;}struct Node //地点{int st,cost,v[10]; //v[10]表示需要工人种类的数目double x,y;} node[N];bool map[N][N]; //判断是否可以在一个点完成后到另一个点int main() { int T,n,m,i,j,ans,k,cs,ct;MCMF mcmf;ios::sync_with_stdio(false);cin>>T;while(T--){cin>>n>>m;cin>>node[0].x>>node[0].y; //工厂的地点for(i=1;i<n;i++){cin>>node[i].x>>node[i].y>>node[i].st>>node[i].cost;for(j=0;j<m;j++)cin>>node[i].v[j];}memset(map,false,sizeof(map));for(i=1;i<n;i++)for(j=1;j<n;j++)if(i!=j && node[i].st+node[i].cost+sqrt(pow(node[i].x-node[j].x,2.0)+pow(node[i].y-node[j].y,2.0))<=node[j].st)map[i][j]=1;ans=0;for(k=0;k<m;k++) //对于每种工人进行一次最小费用最大流{cs=0; //超级源点ct=3*n+1; //超级汇点mcmf.Init(3*n+10);for(i=1;i<n;i++){mcmf.AddEdge(cs,i,node[i].v[k],1);mcmf.AddEdge(i,i+n,node[i].v[k],0);mcmf.AddEdge(cs,i+n*2,node[i].v[k],0);mcmf.AddEdge(i+n,ct,node[i].v[k],0);for(j=1;j<n;j++)if(map[i][j])mcmf.AddEdge(i+n*2,j+n,node[i].v[k],0);}ans+=mcmf.MinCost(cs,ct); //求出每种工人的最小费用并相加}cout<<ans<<endl;} return 0; }
0 0
- HDU ACM 4494 Teamwork 最小费用最大流
- HDU 4494 Teamwork 最小费用最大流
- HDU 4494 Teamwork(最大流或最小费用流)
- hdoj 4494 Teamwork 【最小费用最大流】
- Hdu 4494 Teamwork(最小费用流)
- HDU 4494 Teamwork(最大流-Dinic+最小费用最大流-mcmf)
- hdu 4494 Teamwork(多源多汇最小费用最大流,巧妙构图)
- hdu 4494 Teamwork(费用流)
- HDU 4494 - Teamwork(最大流)
- HDU 4494 Teamwork 费用流/网络流
- HDU 4494 Teamwork 2013通化邀请赛 B题 费用流
- 费用流+建图——Teamwork ( HDU 4494 )
- [ACM模板]MFMC最小费用最大流
- hdu 4494 Teamwork (可行流的最小流)
- HDU 5988 ACM-ICPC Regional QingDao(最小费用最大流)
- 最小费用最大流 HDU 1533
- HDU 1853 最小费用最大流
- hdu 1853 最小费用最大流
- Markdown如何满足中文阅读习惯实现首行缩进
- PHP中内存溢出的问题
- 解决一个千万级别的数组引发的问题的深入剖析
- 黑马程序员——集合框架详解
- MERGE-SORT: INTRODUCTION TO ALGORITHMS
- HDU ACM 4494 Teamwork 最小费用最大流
- 小结1
- BinTree::定义
- 小红帽免费酒店管理系统PMS
- 2015摩根士丹利(Morgan Stanley)实习电话面试
- 一个WordPress站点绑定多个域名
- Hadoop之——自定义分组比较器实现分组功能
- java常见笔试题,易犯错误区
- INSERTION-SORT: INTRODUCTION TO ALGORITHMS