Keyword: How to build a map? How to transform the network stream;
If you think about network flow, you know it's a cost stream.
Then how to build the map;
Here are a few notes:
1. Join the source point, Meeting Point
2. Add (0,x,1,0) to each source point and customer connection
3: The question is how to connect with customers and skilled workers:
First we know that each customer can practice a day cost (I,J) line with each worker, but there is a waiting time
The enumeration wait time is the edge of the connection K*cost (I,J),
But we're not customers. Even a worker is connected to a meeting point, because we know that a worker can only do 1 k*cost (I,J), for example, x this skilled worker can only be the first to even Y, the second even z;
So a clever idea is: to form n+1-n*m+n A new point, let 1-n a customer with these points. (In fact, 1:30 will not say)
In short, we want to be the first customer to choose the younger brother I technical worker's words and only when the contact once.
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include < string> #include <cstdlib> #include <vector> #include <queue> #include <map> #define N 100000# Define INF 0x3f3f3fusing namespace std;struct edge{int v,next,flow,cost,cap;} E[n<<2];int head[n],tot;int pre[n],dis[n];int vis[n];int n,m;int cnt;void init () {tot=0; memset (head,-1,sizeof (Head));} void Add (int u,int v,int cap,int cost) {e[tot].v=v; E[tot].cap=cap; E[tot].cost=cost; e[tot].flow=0; E[tot].next=head[u];; head[u]=tot++; E[tot].v=u; E[tot].cap=0; E[tot].cost=-cost; e[tot].flow=0; E[TOT].NEXT=HEAD[V]; head[v]=tot++;} int SPFA (int s,int t) {queue<int>q; for (int i=0;i<=cnt;i++) {dis[i]=inf; vis[i]=0; Pre[i]=-1; } dis[s]=0; Vis[s]=1; Q.push (s); while (!q.empty ()) {int U=q.front (); Q.pop (); vis[u]=0; for (int i=head[u];i!=-1;i=e[I].next) {int v=e[i].v; if (e[i].cap>e[i].flow&&dis[v]>dis[u]+e[i].cost) {dis[v]=dis[u]+e[i].cost; Pre[v]=i; if (!vis[v]) {vis[v]=1; Q.push (v); }}}} return pre[t]!=-1;} int mincost (int s,int t,int &cost) {int flow=0; cost=0; while (SPFA (s,t)) {int min=inf; for (int i=pre[t];i!=-1;i=pre[e[i^1].v]) min=min (Min,e[i].cap-e[i].flow); for (int i=pre[t];i!=-1;i=pre[e[i^1].v]) {e[i].flow+=min; E[i^1].flow-=min; Cost+=e[i].cost*min; } flow+=min; } return flow;} int Mp[123][123];int Main () {init (); scanf ("%d%d", &m,&n); int s=0; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf ("%d", &mp[i][j]); for (int i=1;i<=n;i++) Add (s,i,1,0); Cnt=n; for (int i=1;i<=m;i++)//mainly here for (int k=1;k<=n;k++) {++cnt; for (int j=1;j<=n;j++) Add (J,cnt,1,k*mp[j][i]); } for (int i=n+1;i<=cnt;i++) Add (i,cnt+1,1,0); cnt++; int t=cnt; int ans; int Flow=mincost (S,t,ans); printf ("%d\n", ans); printf ("%.2lf\n", (double) ans/n); return 0;}
Bzoj 1070: [SCOI2007] Repair car