大意:地球人要占领喵星人的星球,给定地球战舰的初始值以及每年递增的速率,喵星人战舰初始值,以及每年递增的速率,求在一个最小的时间,在改时间内占领全部星球。(一个星球只能占领一个喵星球)
思路:由最后一个条件知道二分匹配,然后二分差值即可,WA了几次,开始以为是数据在0-40000之内,后来发现可能很大,而且精度转换会有误差。
感谢Fire_Hawk_:指出错误,已更正。
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <map> using namespace std; const int maxn = 260; const int maxm = 260*250; struct Edge { int v, next; }edge[maxm]; int xlink[maxn], ylink[maxn]; bool vis[maxn]; int G[maxn][maxn]; int first[maxn]; int cnt; void init() { cnt = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); memset(first, -1, sizeof(first)); } int nx, ny; int n, m, k; void read_graph(int u, int v) { edge[cnt].v = v; edge[cnt].next = first[u], first[u] = cnt++; } int ED(int u) { for(int v = 0; v < ny; v++) if(G[u][v]) { if(vis[v]) continue; vis[v] = 1; if(ylink[v] == -1 || ED(ylink[v])) { xlink[u] = v, ylink[v] = u; return 1; } } return 0; } int MaxMatch() { int ans = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); for(int i = 0; i < nx; i++) if(xlink[i] == -1) { memset(vis, 0, sizeof(vis)); ans += ED(i); } return ans; } inline void readint(int &x) { char c = getchar(); while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) { x = x*10 + c-'0'; c = getchar(); } } inline void writeint(int x) { if(x > 9) writeint(x/10); putchar(x%10+'0'); } struct node { int val, spd; }H[maxn], A[maxn]; int cost[maxn][maxn]; int read_case() { readint(nx), readint(ny); if(!nx) return 0; for(int i = 0; i < nx; i++) readint(H[i].val), readint(H[i].spd); for(int i = 0; i < ny; i++) readint(A[i].val), readint(A[i].spd); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) readint(cost[i][j]); return 1; } const int INF = 0x3f3f3f3f; typedef long long LL; int build(int T) { memset(G, 0, sizeof(G)); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) { LL p = 1LL*(T-cost[i][j])*H[i].spd + H[i].val; LL q = 1LL*A[j].val + 1LL*T*A[j].spd; if(p >= q) G[i][j] = 1; } int ans = MaxMatch(); if(ans >= ny) return 1; return 0; } int BSearch(int x, int y) { int ans = -1; while(x <= y) { int mid = x+(y-x)/2; if(build(mid)) { ans = mid; y = mid-1; } else x = mid+1; } return ans; } void solve() { int ans = -1; ans = BSearch(0, INF); if(ans == -1) { printf("IMPOSSIBLE\n"); return ; } writeint(ans), puts(""); } int main() { while(read_case()) { solve(); } return 0; }
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <map> using namespace std; const int maxn = 260; const int maxm = 260*250; struct Edge { int v, next; }edge[maxm]; int xlink[maxn], ylink[maxn]; bool vis[maxn]; int G[maxn][maxn]; int first[maxn]; int cnt; void init() { cnt = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); memset(first, -1, sizeof(first)); } int nx, ny; int n, m, k; void read_graph(int u, int v) { edge[cnt].v = v; edge[cnt].next = first[u], first[u] = cnt++; } int ED(int u) { for(int v = 0; v < ny; v++) if(G[u][v]) { if(vis[v]) continue; vis[v] = 1; if(ylink[v] == -1 || ED(ylink[v])) { xlink[u] = v, ylink[v] = u; return 1; } } return 0; } int MaxMatch() { int ans = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); for(int i = 0; i < nx; i++) if(xlink[i] == -1) { memset(vis, 0, sizeof(vis)); ans += ED(i); } return ans; } inline void readint(int &x) { char c = getchar(); while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) { x = x*10 + c-'0'; c = getchar(); } } inline void writeint(int x) { if(x > 9) writeint(x/10); putchar(x%10+'0'); } struct node { int val, spd; }H[maxn], A[maxn]; int cost[maxn][maxn]; int read_case() { readint(nx), readint(ny); if(!nx) return 0; for(int i = 0; i < nx; i++) readint(H[i].val), readint(H[i].spd); for(int i = 0; i < ny; i++) readint(A[i].val), readint(A[i].spd); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) readint(cost[i][j]); return 1; } const int INF = 0x6fffffff; typedef long long LL; int build(int T) { memset(G, 0, sizeof(G)); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) { if(T < cost[i][j]) continue; if(H[i].val >= A[j].val+1LL*cost[i][j]*H[j].spd) { G[i][j] = 1; continue ;} LL p = 1LL*(T-cost[i][j])*H[i].spd + H[i].val; LL q = A[j].val + 1LL*T*A[j].spd; if(p >= q) G[i][j] = 1; } int ans = MaxMatch(); if(ans >= ny) return 1; return 0; } int BSearch(int x, int y) { int ans = -1; while(x <= y) { int mid = x+(y-x)/2; if(build(mid)) { ans = mid; y = mid-1; } else x = mid+1; } return ans; } void solve() { int ans = -1; ans = BSearch(0, INF); if(ans == -1) { printf("IMPOSSIBLE\n"); return ; } printf("%d\n", ans); } int main() { while(read_case()) { solve(); } return 0; }
/*已更正*/ #include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <map> using namespace std; const int maxn = 260; const int maxm = 260*250; struct Edge { int v, next; }edge[maxm]; int xlink[maxn], ylink[maxn]; bool vis[maxn]; int G[maxn][maxn]; int first[maxn]; int cnt; void init() { cnt = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); memset(first, -1, sizeof(first)); } int nx, ny; int n, m, k; void read_graph(int u, int v) { edge[cnt].v = v; edge[cnt].next = first[u], first[u] = cnt++; } int ED(int u) { for(int v = 0; v < ny; v++) if(G[u][v]) { if(vis[v]) continue; vis[v] = 1; if(ylink[v] == -1 || ED(ylink[v])) { xlink[u] = v, ylink[v] = u; return 1; } } return 0; } int MaxMatch() { int ans = 0; memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); for(int i = 0; i < nx; i++) if(xlink[i] == -1) { memset(vis, 0, sizeof(vis)); ans += ED(i); } return ans; } inline void readint(int &x) { char c = getchar(); while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) { x = x*10 + c-'0'; c = getchar(); } } inline void writeint(int x) { if(x > 9) writeint(x/10); putchar(x%10+'0'); } struct node { int val, spd; }H[maxn], A[maxn]; int cost[maxn][maxn]; int read_case() { readint(nx), readint(ny); if(!nx) return 0; for(int i = 0; i < nx; i++) readint(H[i].val), readint(H[i].spd); for(int i = 0; i < ny; i++) readint(A[i].val), readint(A[i].spd); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) readint(cost[i][j]); return 1; } const int INF = 0x6fffffff; typedef long long LL; int build(int T) { memset(G, 0, sizeof(G)); for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) { if(T < cost[i][j]) continue; if(H[i].val >= A[j].val+1LL*cost[i][j]*H[j].spd) { G[i][j] = 1; continue ;} LL p = 1LL*(T-cost[i][j])*H[i].spd + H[i].val; LL q = A[j].val + 1LL*T*A[j].spd; if(p >= q) G[i][j] = 1; } int ans = MaxMatch(); if(ans >= ny) return 1; return 0; } int BSearch(int x, int y) { int ans = -1; while(x <= y) { int mid = x+(y-x)/2; if(build(mid)) { ans = mid; y = mid-1; } else x = mid+1; } return ans; } void solve() { int ans = -1; ans = BSearch(0, INF); if(ans == -1) { printf("IMPOSSIBLE\n"); return ; } printf("%d\n", ans); } int main() { while(read_case()) { solve(); } return 0; }