题意:n个人类星球和m个外星人星球,每个星球(包括外星人的)都有一个初始的飞船数sh1[i],还有一个每年生产的飞船数p[i],还有一个n*m的矩阵d,d[i,j]表示从人类星球i到外星人星球j的年数(..年啊),当一个人类星球i可以击败一个外星人星球j的唯一条件是在出发年数ye,(ye-d[i,j])*p[i]+sh1[i]>=ye*p[j]+sh1[j] 的时候,人类星球i可以击败外星球j,不考虑外星球攻击人类星球(这不欺负人吗?),每个人星球只能攻击一个外星球,每个外星球也只能被一个人星球攻击,问最早在哪年开始攻击可以把所有外星球都打掉.
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define inf 1e11 #define LL long long using namespace std; const int N=500; int map[N][N]; int hp[N]; int hshill[N]; int ap[N]; int ashill[N]; int n,m; int edge[N][N]; int cx[N]; int cy[N]; int mark[N]; void builtmap(LL mid) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { LL val=(LL)(mid-edge[i][j])*hp[i]+hshill[i]-mid*ap[j]-ashill[j]; if(val>=0) map[i][j]=1; } } int dfs(int u) { for(int v=1;v<=m;v++) { if(map[u][v]&&!mark[v]) { mark[v]=1; if(cy[v]==-1||dfs(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int maxmatch() { int res=0; memset(cx,0xff,sizeof(cx)); memset(cy,0xff,sizeof(cy)); for(int i=1;i<=n;i++) { if(cx[i]==-1) { memset(mark,0,sizeof(mark)); res+=dfs(i); } } return res; } int main() { while(scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; for(int i=1;i<=n;i++) cin>>hshill[i]>>hp[i]; for(int j=1;j<=m;j++) cin>>ashill[j]>>ap[j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>edge[i][j]; LL lef=0,rig=inf,ans=-1; while(lef<=rig) { LL mid=(lef+rig)/2; memset(map,0,sizeof(map)); builtmap(mid); int tmp=maxmatch(); if(tmp==m) ans=mid,rig=mid-1; else lef=mid+1; } if(ans==-1) cout<<"IMPOSSIBLE"<<endl; else cout<<ans<<endl; } return 0; }