原题链接:http://codeforces.com/gym/100733/problem/I
题意
有两颗树(只是树,不是数据结构),每棵树上有不同高度的树枝,然后有m只猴子在某棵树的前m高的树枝上睡觉。早上的时候,他们要到地上,但他们只能从一棵树上跳到另一棵树上,并且跳的高度差也有限制,每个树枝仅能被一只猴子踩过。问你,猴子们是否能够跳到另一棵树最低的m个树枝上。
题解
就每个点拆成两个点,然后连边,所有边的容量都为1,然后跑发最大流,考察是否为滿流即可。
代码
#include<iostream> #include<stack> #include<vector> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdio> #include<queue> #define MAX_S (1<<10)+10 #define MAX_V 2222 #define MAX_N MAX_V #define INF 1000000009 using namespace std; struct edge { int to, cap, rev; bool isRev; edge(int t, int c, int r, bool i) : to(t), cap(c), rev(r), isRev(i) { } edge() { } }; template <class T> inline bool scan_d(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!=' -' &&(c<'0' ||c>'9' )) c=getchar(); sgn=(c==' -' )?-1:1; ret=(c==' -' )?0:(c-'0' ); while(c=getchar(),c>='0' &&c<='9' ) ret=ret*10+(c-'0' ); ret*=sgn; return 1; } vector<edge> G[MAX_N]; int level[MAX_V]; int iter[MAX_V]; void init(int totNode) { for (int i = 0; i <= totNode; i++) G[i].clear(); memset(level, 0, sizeof(level)); memset(iter, 0, sizeof(iter)); } void add_edge(int from,int to,int cap) { G[from].push_back(edge (to, cap, G[to].size(),0)); G[to].push_back(edge (from, 0, G[from].size() - 1,1)); } void bfs(int s) { queue<int> que; memset(level, -1, sizeof(level)); level[s] = 0; que.push(s); while (!que.empty()) { int v = que.front(); que.pop(); for (int i = 0; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; que.push(e.to); } } } } int dfs(int v,int t,int f) { if (v == t)return f; for (int &i = iter[v]; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s,int t) { int flow = 0; for (; ;) { bfs(s); if (level[t] < 0)return flow; memset(iter, 0, sizeof(iter)); int f; while ((f = dfs(s, t, INF)) > 0) { flow += f; } } } int ha[MAX_N],hb[MAX_N]; int m,na,nb,t; int S=2212; int T=2211; bool cmp(int a,int b){ return a>b; } int main() { cin.sync_with_stdio(false); cin >> m >> na >> nb >> t; for (int i = 0; i < na; i++)cin >> ha[i]; for (int i = 0; i < nb; i++)cin >> hb[i]; sort(ha, ha + na,cmp); sort(hb, hb + nb,cmp); for(int i=0;i<m;i++) add_edge(S,i,1); for(int i=0;i<na;i++) add_edge(i,i+na,1); for(int i=1;i<=m;i++) add_edge((nb-i)+na+na+nb,T,1); for(int i=0;i<nb;i++) add_edge(i+na+na,i+na+na+nb,1); for(int i=0;i<na;i++) for(int j=0;j<nb;j++) if(abs(ha[i]-hb[j])<t){ add_edge(i+na,j+2*na,1); add_edge(j+2*na+nb,i,1); } int f=max_flow(S,T); if(f>=m){ cout<<"S"<<endl; return 0; } init(MAX_N); for(int i=0;i<m;i++) add_edge(S,i+2*na,1); for(int i=0;i<na;i++) add_edge(i,i+na,1); for(int i=1;i<=m;i++) add_edge((na-i)+na,T,1); for(int i=0;i<nb;i++) add_edge(i+na+na,i+na+na+nb,1); for(int i=0;i<na;i++) for(int j=0;j<nb;j++) if(abs(ha[i]-hb[j])<t){ add_edge(i+na,j+2*na,1); add_edge(j+2*na+nb,i,1); } f=max_flow(S,T); if (f >= m) cout << "S" << endl; else cout << "N" << endl; return 0; }