Title Address: http://acm.hdu.edu.cn/showproblem.php?pid=4494
Idea: Each attribute person does not interfere with each other, runs m times the cost flow, the result accumulates. Super Source point 0, Super Sink point 2*n-1. Split each point into two points one for yourself, and another representation to be available to others. The source points to each point that represents itself a capacity of INF, the cost of 1 of the edge, indicating the starting point there are countless people each to choose a person to spend 1. For each split point, the source point has a capacity of kind[i] (number of people required in the I), and the cost is 0 sides. Represents the current point at which a maximum of kind[i] can be provided at a cost of 0. For the I task, if worker[i].b+worker[i].p+dist<=worker[j].b, I will be disassembled to point to the point of J's own edge, indicating that the worker can be provided.
#include <cstdio> #include <queue> #include <cmath> #include <vector> #include <cstring># include<iostream> #include <algorithm> #define debuusing namespace std;const int Maxn=500;const int inf= 0x3f3f3f3f;typedef Long long ll;struct edge{int from,to,cap,flow,cost; Edge (int u,int v,int c,int f,int W): From (U), to (v), Cap (c), Flow (f), Cost (w) {}};struct node{int kind[6]; int b,p,x,y;}; int s,t,stx,sty; Node worker[maxn];vector<edge> edges;vector<int> g[maxn];int n,m,p[maxn],a[maxn];int INQ[MAXN],D[MAXN]; LL cost;void init (int n) {edges.clear (); for (int i=0; i<=n; i++) G[i].clear ();} void addedges (int from,int to,int cap,int cost) {Edges.push_back (Edge (from,to,cap,0,cost)); Edges.push_back (Edge (to,from,0,0,-cost)); int tot=edges.size (); G[from].push_back (tot-2); G[to].push_back (tot-1);} BOOL BF (int s,int t,int& flow,ll& cost) {//cout<<n<< "" <<m<<endl; cout<< "Flag" <<endl; for (int i=0; i<=2*n; i++) D[i]=inf; memset (inq,0,sizeof (INQ)); d[s]=0,inq[s]=1,p[s]=0; Queue<int> Q; Q.push (s), A[s]=inf; while (!q.empty ()) {int U=q.front (); Q.pop (), inq[u]=0; for (int i=0; i<g[u].size (); i++) {edge& e=edges[g[u][i]]; if (e.cap>e.flow&&d[e.to]>d[u]+e.cost) {d[e.to]=d[u]+e.cost; P[e.to]=g[u][i]; A[e.to]=min (A[u],e.cap-e.flow); if (!inq[e.to]) {Q.push (e.to); Inq[e.to]=1; }}}} if (D[t]==inf) return false; FLOW+=A[T]; cost+= (LL) d[t]* (LL) a[t]; for (int u=t; u!=s; u=edges[p[u]].from) {edges[p[u]].flow+=a[t]; EDGES[P[U]^1].FLOW-=A[T]; } return true; int mincostmaxflow (int s,int t,ll& cost) {int flow=0; cost=0; while (BF (s,t,flow,cost)); return cost;} Double Dist (NodeA,node b) {return sqrt (1.0* (a.x-b.x) * (a.x-b.x) +1.0* (A.Y-B.Y) * (A.Y-B.Y));} void make (int x) {init (2*n); for (int i=1; i<=n-1; i++) {addedges (s,i,inf,1); Addedges (i,t,worker[i].kind[x],0); Addedges (s,i+n-1,worker[i].kind[x],0); cout<<s<< "<<i<<" "<<INF<<" "<<1<<endl; cout<<i<< "<<t<<" "<<worker[i].kind[x]<<" "<<0<<endl; cout<<s<< "<<i+n-1<<" "<<worker[i].kind[x]<<" "<<0<<endl; for (int j=1; j<=n-1; J + +) {if (i==j) continue; Double Dis=dist (worker[i],worker[j]); if (worker[i].b+worker[i].p+dis<=worker[j].b) {//cout<<i+n-1<< "" "<<j<< ;" "<<INF<<" "<<0<<endl; Addedges (i+n-1,j,inf,0); }}}//cout<< "flag" <<ENDL;} VoiD solve () {int ans=0; for (int i=1, i<=m; i++) {make (i); cout<<s<< "" <<t<<endl; Ans+=mincostmaxflow (S,t,cost); } printf ("%d\n", ans);} int main () {#ifdef debug Freopen ("In.in", "R", stdin); #endif//debug int cas; scanf ("%d", &cas); while (cas--) {scanf ("%d%d", &n,&m); scanf ("%d%d", &stx,&sty); s=0,t=2* (n-1) +1; cout<<s<< "" <<t<<endl; for (int i=1; i<=n-1; i++) {scanf ("%d%d%d%d",&worker[i].x,&worker[i].y,&worker[i].b,& WORKER[I].P); for (int j=1; j<=m; j + +) scanf ("%d", &worker[i].kind[j]); } solve (); } return 0;}
Hdu 4494 Teamwork (minimum charge flow)