POJ 3498 March of the Penguins (enumeration + maximum stream)
http://poj.org/problem?id=3498
The following:
There are N (n<=100) ice cubes in the x,y coordinate system ... Some of the ice cubes have several penguins. Each penguin jumps at a maximum of m distance at a time. An ice Cube has mi a penguin to leave . Will disappear. Ask what ice cubes can be used as rendezvous points. Is that all penguins can get to this ice.
Analysis:
First we enumerate each piece of ice and see if the ice, if it's a rendezvous point, is all penguins can get to the ice.
Build diagram:
Divide each piece of ice into two dots I and i+n. I represents the point into the I ice ( can have countless penguins come over, so from other ice to I have side, volume for INF) i+n shows the point from I ice cubes ( up to only mi penguins jump out from here, so from I to i+n there are sides, and capacity is Mi)
From source point S to I have side (s, I, I point initial penguin number).
From I to i+n there are sides (I, I+n, Mi). It means that the first block of ice is up to only mi a penguin can jump away.
Because I+n represents the first jumping point, so if the distance between the ice cubes I and J <= penguins can jump distances m, there are sides (I+n, J, INF)
Suppose we are currently enumerating block X blocks of ice as the rendezvous point, then (x is divided into X and x+n two points) x is the meeting point ( not the x+n point oh ), we only calculate to the x point of the flow is the total number of penguins can be.
Note The final result output number is counted from 0.
AC Code:
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector
> #define INF 1e9 using namespace std;
const int maxn=200+5;
struct Edge {int from,to,cap,flow;
Edge () {} edge (int f,int t,int c,int FL): From (f), to (T), Caps (c), Flow (fl) {}};
struct Dinic {int n,m,s,t;
Vector<edge> edges;
Vector<int> G[MAXN];
BOOL VIS[MAXN];
int CUR[MAXN];
int D[MAXN];
void init (int n,int s,int t) {this->n=n, this->s=s, this->t=t;
Edges.clear ();
for (int i=0;i<n;i++) g[i].clear ();
} void Addedge (int from,int to,int cap) {Edges.push_back (Edge (from,to,cap,0));
Edges.push_back (Edge (to,from,0,0));
M=edges.size ();
G[from].push_back (m-2);
G[to].push_back (m-1);
BOOL BFS () {queue<int> Q;
memset (Vis) (vis,0,sizeof);
Vis[s]=true;
d[s]=0;
Q.push (s);while (! Q.empty ()) {int X=q.front ();
Q.pop ();
for (int i=0;i<g[x].size (); ++i) {edge& e=edges[g[x][i]];
if (!vis[e.to] && e.cap>e.flow) {vis[e.to]=true;
D[e.to] = d[x]+1;
Q.push (e.to);
}} return vis[t];
int DFS (int x,int a) {if (x==t | | a==0) return A;
int flow=0,f;
For (int& i=cur[x];i<g[x].size (); ++i) {edge& e=edges[g[x][i]];
if (d[e.to]==d[x]+1 && (F=dfs (E.to,min (A,e.cap-e.flow)) >0) {E.flow +=f;
Edges[g[x][i]^1].flow-=f;
Flow+=f;
A-=f;
if (a==0) break;
} return flow;
int Max_flow () {int ans=0;
while (BFS ()) { memset (cur,0,sizeof (cur));
Ans+=dfs (S,inf);
return ans;
}}DC;
struct Node {double x,y;
int n,m;
Double Get_dist (node& b) const {return (x-b.x) * (x-b.x) + (Y-B.Y) * (Y-B.Y));
}}NODES[MAXN];
int n,num;//n is the number of ice cubes, num is the number of penguins double limit;
BOOL a[maxn][maxn];//is feasible matrix bool solve (int t) {dc.init (n*2+1, 0, T); for (int i=1;i<=n;i++) if (NODES[I].N) DC.
Addedge (0, I, NODES[I].N); for (int i=1;i<=n;i++) if (NODES[I].M) DC.
Addedge (i, I+n, NODES[I].M); for (int i=1;i<=n;i++) (int j=i+1;j<=n;j++) if (A[i][j]) {DC.
Addedge (I+n,j,inf); DC.
Addedge (J+n,i,inf);
return Dc.max_flow () = = num;
int main () {int T; scanf ("%d", &t);
while (t--) {num=0;//Penguin number scanf ("%d%lf", &n,&limit); for (int i=1;i<=n;i++) {scanf ("%lf%lf%d%d", &nodes[i].x,&nodes[i].y,&nodes[i].n,&nod
ES[I].M); num + + nodes[i].n;//count Penguins} for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) {if (i==j) a[i
][j]=true;
Else a[i][j]= (Nodes[i].get_dist (nodes[j)) <= limit*limit);
Vector<int> ans;
for (int i=1;i<=n;i++) {if (Solve (i)) ans.push_back (i);
} if (Ans.size () ==0) printf (" -1\n"); else {for (int i=0;i<ans.size () -1;++i) printf ("%d", ans[i]-1);//output number from 0 count printf ("%d\n",
Ans[ans.size () -1]-1);
} return 0;
}