題意:給出n(n <= 150)個城市和m(m <= 5000)個航班,每一個航班有出發地、到達地、乘坐人數、起飛時間和降落時間(時間用時和分表示),求一個指定城市到另外一個指定城市在規定的最晚時間前能夠過去多少人(換航班的間隔至少須要30分鐘)。ios
一、爲了考慮時間的因素,把航班拆成兩個點v1與v2,則v1 -> v2的容量爲航班的乘坐人數;this
二、若兩趟航班之間能夠轉(即第一個航班的降落時間與第二個航班的起飛時間至少相差30分鐘),那麼就將第一個航班的v2連到第二個航班的v1上去,容量爲正無窮;spa
三、另設兩個點分別表明出發與到達的指定城市 start 和 end,則:全部出發點爲 start 的航班,連start -> 航班的v1,全部終點爲 end 的航班,且到達時間在規定最晚時間以前的,連 航班的v2 -> end。容量均爲正無窮;code
四、對 start 至 end 求一遍最大流便可。blog
代碼以下:get
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<list> #define fin freopen("in.txt", "r", stdin) #define fout freopen("out.txt", "w", stdout) #define pr(x) cout << #x << " : " << x << " " #define prln(x) cout << #x << " : " << x << endl #define Min(a, b) a < b ? a : b #define Max(a, b) a < b ? b : a typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const double pi = acos(-1.0); const double EPS = 1e-6; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const ll MOD = 1e9 + 7; using namespace std; #define NDEBUG #include<cassert> const int MAXN = 200 + 10; const int MAXT = 10000 + 10; struct Edge{ int from, to, cap, flow; Edge(int a, int b, int c, int d) : from(a), to(b), cap(c), flow(d) {} }; struct Dinic{ int n, m, s, t; vector<Edge> edges; vector<int> G[MAXT]; bool vis[MAXT]; int d[MAXT]; int cur[MAXT]; void init(int k){ edges.clear(); for(int i = 0; i < k; ++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(){ memset(vis, false, sizeof vis); queue<int> q; q.push(s); d[s] = 0; vis[s] = true; 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[x] + 1 == d[e.to] && (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 Maxflow(int s, int t){ this->s = s; this->t = t; int flow = 0; while(bfs()){ memset(cur, 0, sizeof cur); flow += dfs(s, INT_INF); } return flow; } }dic; map<string, int> mp; int sumid, latest, n, m; int getID(string t){ if(mp.count(t)) return mp[t]; return mp[t] = ++sumid; } int getTime(char s[]){ return 60 * ((s[0] - '0') * 10 + s[1] - '0') + 10 * (s[2] - '0') + s[3] - '0'; } struct Node{ int u, v, t, t1, t2; }p[MAXT]; int main(){ while(scanf("%d", &n) == 1){ mp.clear(); sumid = 0; char s1[10], s2[10]; scanf("%s%s", s1, s2); int s = getID(s1), t = getID(s2); scanf("%s%d", s1, &m); latest = getTime(s1); for(int i = 1; i <= m; ++i){ scanf("%s%s", s1, s2); p[i].u = getID(s1); p[i].v = getID(s2); scanf("%d%s%s", &p[i].t, s1, s2); p[i].t1 = getTime(s1); p[i].t2 = getTime(s2); } dic.init(2 * m + 10); for(int i = 1; i <= m; ++i){ dic.AddEdge(i, i + m, p[i].t); if(p[i].u == s) dic.AddEdge(0, i, INT_INF); if(p[i].v == t && p[i].t2 <= latest) dic.AddEdge(i + m, 2 * m + 1, INT_INF); for(int j = 1; j <= m; ++j){ if(i == j) continue; if(p[i].v == p[j].u && p[j].t1 - p[i].t2 >= 30) dic.AddEdge(i + m, j, INT_INF); } } printf("%d\n", dic.Maxflow(0, 2 * m + 1)); } return 0; }