solve 2(310 / 634)
J题题意搞错一口大锅。
dzcH题结论猜对了,只是树上二分图不用匈牙利算法,能换成更高效的写法。
高斯消元 + 矩阵快速幂
H Monkeys
二分图结论
J Schedule
优先队列
<qj>
题意:
有n个任务,给你开始时间和结束时间,有无数台机器,每台机器可以在同一时间最多处理一个任务,并且开机之后,只能关一次机,不能中途关机又开机。
问至少需要多少机器,在这么多台机器的情况下,最少花费多少。(花费 = 每台机器关机时间 - 开机时间 的和。)
思路:
1.对于至少需要多少台机器,用一个优先队列维护一下就可以求出。
2.求最少花费,需要再开一个优先队列,两个优先队列分别维护:最早未就绪机器,最迟已就绪机器。
3.我们把任务用最迟已就绪机器处理,一定最优。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct node{ int s,e; node(int s=0,int e=0):s(s),e(e){} friend bool operator < (node a,node b){ if(a.s==b.s)return a.e>b.e; return a.s<b.s; } }p[100005]; int n; priority_queue<int,vector<int>,greater<int> >q; priority_queue<int,vector<int>,less<int> > qq; int main(){ int t;cin>>t; while(t--){ while(!q.empty())q.pop(); while(!qq.empty())qq.pop(); int ans1=1; ll ans2=0; cin>>n; for(int i=1;i<=n;i++){ scanf("%d%d",&p[i].s,&p[i].e); } sort(p+1,p+1+n); q.push(p[1].e); for(int i=2;i<=n;i++){ int val = q.top(); if(val<=p[i].s){ q.pop();q.push(p[i].e); } else { q.push(p[i].e); ans1 = max(ans1,(int)q.size()); } } while(!q.empty())q.pop(); for(int i=1;i<=ans1;i++)qq.push(0); for(int i=1;i<=n;i++){ while(!q.empty() && q.top() <= p[i].s){ qq.push(q.top());q.pop(); } int val = qq.top(); if(val==0)ans2-=p[i].s; qq.pop(); q.push(p[i].e); } while(!q.empty()){ ans2+=q.top();q.pop(); } while(!qq.empty()){ ans2+=qq.top();qq.pop(); } cout<<ans1<<" "<<ans2<<endl; } return 0; }
次短路