#include <iostream> #include <vector> #include <queue> #include <set> #include <algorithm> using namespace std; const int MAXV=500; const int MAX_CAP = 1000000000; vector<vector<int>> G; int cap[MAXV][MAXV]; int add_vertex() { G.push_back(vector<int>(0)); return G.size() - 1; } void add_edge(int from, int to, int c) { G[from].push_back(to); if(!cap[to][from]) G[to].push_back(from); cap[from][to]=c; } int find_path(int sink, int source) { queue<int> Q; Q.push(source); vector<bool> visited = vector<bool>(G.size(), false); vector<int> from = vector<int>(G.size(),-1); visited[source]=true; while(!Q.empty()) { int p = Q.front();Q.pop(); if(p==sink)break; for(auto it = G[p].begin();it!=G[p].end();it++){ int q = *it; if(cap[p][q]==0 || visited[q])continue; from[q]=p; visited[q]=true; Q.push(q); } } if(from[sink]==-1) return 0; int max_cap = MAX_CAP; int q = sink; while (from[q]!=-1) { int p = from[q]; max_cap = min(max_cap, cap[p][q]); q = p; } q = sink; while (from[q]!=-1) { int p = from[q]; cap[p][q]-=max_cap; cap[q][p]+=max_cap; q = p; } return max_cap; } int max_flow(int sink, int source) { int res =0; while(true) { int flow = find_path(sink, source); if(flow==0)break; res += flow; } return res; } int main() { int n,m; cin >>n>>m; int P[n]; int K[n]; int C[n]; int task[n]; int total_task =0; for(int i=0;i<n;i++){ cin >> P[i]>>K[i]>>C[i]; total_task+=C[i]; } int source = add_vertex(); int sink = add_vertex(); for(int i=0;i<n;i++){ task[i]=add_vertex(); add_edge(task[i], sink, C[i]); } vector<pair<int,int>> events; for(int i=0;i<n;i++) { events.push_back(make_pair(P[i], i+1)); events.push_back(make_pair(K[i], -i-1)); } sort(events.begin(), events.end()); set<int>open; int prev =0; for(auto it = events.begin();it!=events.end();++it) { int t = it->first; int id = it->second; int dt = t - prev; int oc = open.size(); if(oc > 0 && dt >0) { //cout << "SEGMENT "<<prev<<" - "<<t<<": "; int processed = min(m, oc) * dt; int pv = add_vertex(); // cout <<" total processed: "<<processed<<endl; add_edge(source, pv, processed); for(auto it = open.begin();it!=open.end();++it) { add_edge(pv, task[*it], dt); // cout <<" task "<<*it<<endl; } } if(id>0) { id--; open.insert(id); } else { id = -id - 1; open.erase(id); } prev = t; } int flow = max_flow(sink, source); if(flow==total_task)cout <<"TAK\n"; else cout <<"NIE\n"; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <iostream> #include <vector> #include <queue> #include <set> #include <algorithm> using namespace std; const int MAXV=500; const int MAX_CAP = 1000000000; vector<vector<int>> G; int cap[MAXV][MAXV]; int add_vertex() { G.push_back(vector<int>(0)); return G.size() - 1; } void add_edge(int from, int to, int c) { G[from].push_back(to); if(!cap[to][from]) G[to].push_back(from); cap[from][to]=c; } int find_path(int sink, int source) { queue<int> Q; Q.push(source); vector<bool> visited = vector<bool>(G.size(), false); vector<int> from = vector<int>(G.size(),-1); visited[source]=true; while(!Q.empty()) { int p = Q.front();Q.pop(); if(p==sink)break; for(auto it = G[p].begin();it!=G[p].end();it++){ int q = *it; if(cap[p][q]==0 || visited[q])continue; from[q]=p; visited[q]=true; Q.push(q); } } if(from[sink]==-1) return 0; int max_cap = MAX_CAP; int q = sink; while (from[q]!=-1) { int p = from[q]; max_cap = min(max_cap, cap[p][q]); q = p; } q = sink; while (from[q]!=-1) { int p = from[q]; cap[p][q]-=max_cap; cap[q][p]+=max_cap; q = p; } return max_cap; } int max_flow(int sink, int source) { int res =0; while(true) { int flow = find_path(sink, source); if(flow==0)break; res += flow; } return res; } int main() { int n,m; cin >>n>>m; int P[n]; int K[n]; int C[n]; int task[n]; int total_task =0; for(int i=0;i<n;i++){ cin >> P[i]>>K[i]>>C[i]; total_task+=C[i]; } int source = add_vertex(); int sink = add_vertex(); for(int i=0;i<n;i++){ task[i]=add_vertex(); add_edge(task[i], sink, C[i]); } vector<pair<int,int>> events; for(int i=0;i<n;i++) { events.push_back(make_pair(P[i], i+1)); events.push_back(make_pair(K[i], -i-1)); } sort(events.begin(), events.end()); set<int>open; int prev =0; for(auto it = events.begin();it!=events.end();++it) { int t = it->first; int id = it->second; int dt = t - prev; int oc = open.size(); if(oc > 0 && dt >0) { //cout << "SEGMENT "<<prev<<" - "<<t<<": "; int processed = min(m, oc) * dt; int pv = add_vertex(); // cout <<" total processed: "<<processed<<endl; add_edge(source, pv, processed); for(auto it = open.begin();it!=open.end();++it) { add_edge(pv, task[*it], dt); // cout <<" task "<<*it<<endl; } } if(id>0) { id--; open.insert(id); } else { id = -id - 1; open.erase(id); } prev = t; } int flow = max_flow(sink, source); if(flow==total_task)cout <<"TAK\n"; else cout <<"NIE\n"; return 0; } |